黑马程序员技术交流社区
标题:
线程模拟生产者消费者的问题!
[打印本页]
作者:
ying
时间:
2013-1-7 20:22
标题:
线程模拟生产者消费者的问题!
本帖最后由 ying 于 2013-1-8 13:12 编辑
/*
线程模拟生产者与消费者
要求:生产一个消费一个
*/
class ProducterConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource(); //定义商品资源
Producter pro = new Producter(r);//创建生产者对象
Consumer son = new Consumer(r); //创建消费者对象
//创建两个生产者即两个线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
//创建两个消费者即两个线程
Thread t3 = new Thread(son);
Thread t4 = new Thread(son);
//启动四个线程并执行相应的run方法
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
定义商品类
*/
class Resource
{
private String name; //商品的名字
private int count =1; //商品的编号
private boolean flag = false;
public synchronized void set(String name)
{
if(flag)
try{this.wait();}catch(Exception e){}
this.name = name + "--" + count++;//
System.out.println(Thread.currentThread().getName() + "...生产者 " + this.name);
flag = true;
this.notify();
}
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(Exception e){}
System.out.println(Thread.currentThread().getName() + "...消费者————" + this.name);
flag = false;
this.notify();
}
}
// 商品的生产者
class Producter implements Runnable
{
private Resource res;
Producter(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("商品+");
}
}
}
//商品的消费者
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
复制代码
我的代码的生产者和消费者不和谐了,有时候生产一个会消费两个或者生产两个消费一个!我弄了半天也没弄懂到底是错在哪里了!请高手指教!!
ConsuProduc.jpg
(87.65 KB, 下载次数: 72)
下载附件
2013-1-7 20:21 上传
作者:
蔡少凯
时间:
2013-1-7 20:48
将if换成while循环 代码中的this.notify(); 改成notifyAll();
作者:
熊永标
时间:
2013-1-7 20:54
package demo1;
/*
线程模拟生产者与消费者
要求:生产一个消费一个
*/
class ProducterConsumerDemo {
public static void main(String[] args) {
Resource r = new Resource(); // 定义商品资源
Producter pro = new Producter(r);// 创建生产者对象
Consumer son = new Consumer(r); // 创建消费者对象
// 创建两个生产者即两个线程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
// 创建两个消费者即两个线程
Thread t3 = new Thread(son);
Thread t4 = new Thread(son);
// 启动四个线程并执行相应的run方法
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
* 定义商品类
*/
class Resource {
private String name; // 商品的名字
private int count = 1; // 商品的编号
private boolean flag = false;
public synchronized void set(String name) {
while (flag)
try {
this.wait();
} catch (Exception e) {
}
this.name = name + "--" + count++;//
System.out.println(Thread.currentThread().getName() + "...生产者 "
+ this.name);
flag = true;
this.notifyAll();
}
public synchronized void out() {
while (!flag)
try {
this.wait();
} catch (Exception e) {
}
System.out.println(Thread.currentThread().getName() + "...消费者————"
+ this.name);
flag = false;
this.notifyAll();
}
}
// 商品的生产者
class Producter implements Runnable {
private Resource res;
Producter(Resource res) {
this.res = res;
}
public void run() {
while (true) {
res.set("商品+");
}
}
}
// 商品的消费者
class Consumer implements Runnable {
private Resource res;
Consumer(Resource res) {
this.res = res;
}
public void run() {
while (true) {
res.out();
}
}
}
复制代码
我把你的代码改了一下,运行正常,你的错误主要有两个,
第一:判断是用while,而不是if,因为多个线程可能在if的下面,当线程醒来时,根本就有再进行判断,而此时由于一个线程的消费而使务件不成立了,但是由于线程都在if下面,所以根本不需要再次判断就直接再次消费而引起的。
第二:你必须唤醒全部的线程,要不然因为线程的唤醒是随机的,不确定的,当消费了之的,再次唤醒的双是在等待当中的消费线程时,就出出了多消费的情况。如果你使用了多次循还判断,那么必须唤醒的全部线程,然不然可能出现死锁的情况。因为有可能全部的线程都处于等待唤醒的状态。
作者:
郭金龙
时间:
2013-1-8 10:50
类似需要有加锁的操作。我也记得不是很清楚,但是毕老师在多线程视频中好像讲的很清楚,建议你看一下!!好像是用等待唤醒机制!
作者:
ying
时间:
2013-1-8 11:35
嗯!谢谢各位!问题解决了!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2