黑马程序员技术交流社区
标题:
多线程中生产者和消费者的问题
[打印本页]
作者:
李贺晓
时间:
2012-10-22 22:07
标题:
多线程中生产者和消费者的问题
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resourse re=new Resourse();
Producer po=new Producer(re);
Consumer co=new Consumer(re);
Thread t1=new Thread(po);
Thread t2=new Thread(po);
Thread t3=new Thread(co);
Thread t4=new Thread(co);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resourse
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name)
{
if(flag)
try
{
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
{
wait();
}
catch (Exception e)
{
}
System.out.println(Thread.currentThread().getName()+".........消费商品......"+this.name);
flag=false;
this.notify();
}
}
class Producer implements Runnable
{
private Resourse re;
Proudcer(Resourse re)
{
this.re=re;
}
public void run()
{
System.out.println(re.set("++商品++"));
}
}
class Consumer implements Runnable
{
private Resourse re;
Consumer(Resourse re)
{
this.re=re;
}
public void run()
{
System.out.println(re.out());
}
}
当t1运行过后,把flag置为true;然后t1放弃资格,t2判断flag不为false,也放弃资格,当t3运行过之后,flag置为false,t3放弃资格,这个时候t1获取资格,然后t1判断flag为false,执行完成后,这个时候t2获取资格,毕老师在视频中讲的是,这个时候t2不在判断flag,而是直接执行try下面的代码,这是为什么,这个时候不是应该先判断flag是否为false呢???
作者:
李铁
时间:
2012-10-23 00:13
因为用的不是while(flag),不是while(){}结构,所以不会循环。
带你走一遍思路,你就明白了!
开始t1执行后,生产一个商品,flag为true,1放弃资格,t2判断flag为true,t2放弃资格。t3开始执行,判断flag为true,消费一个商品,flag为false, t4判断flag为false, t4放弃资格
当t1获得执行权后,执行完后flag为true,生产一个商品,唤醒了t2 。t1放弃资格,t2就直接往下执行了,然后又输出一个“生产者”,所以出现了生产两个商品的情况。
解决的方法就是将if改为while结构后,t2就不会再生产了,直接放弃资格,最后导致全部等待,所以要把this.notify()改为this.notifyAll()就可以解决了。
作者:
李贺晓
时间:
2012-10-23 08:44
李铁 发表于 2012-10-23 00:13
因为用的不是while(flag),不是while(){}结构,所以不会循环。
带你走一遍思路,你就明白了!
开始t1执行后 ...
t2第一次放弃资格的时候,下一次唤醒t2的时候,t2不是还应该重新判断flag,此时的flag还是为true,这个时候t2不是还是应该放弃资格呢,怎么会顺序往下执行呢
作者:
灵感
时间:
2012-10-23 11:26
本帖最后由 严学韦 于 2012-10-23 12:58 编辑
if(flag)
try
{
wait();
}
catch (Exception e)
{
}
哥们,是这样子的,毕老师不是每次都用while(true)让程序执行多次吗?
他为什么不用if(true)让代码执行多次呢?你应该知道原因了吧?
while执行多次,if执行单次
线程2是走了if之后放弃资格的
所以当线程2从放弃资格到获取到资格时它就不再判断flag了,直接往下走了
如果将if改成while的话线程2必须再次判断flag
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2