黑马程序员技术交流社区

标题: 线程唤醒问题? [打印本页]

作者: 郑庆伟    时间: 2012-7-3 13:16
标题: 线程唤醒问题?
本帖最后由 郑庆伟 于 2012-7-4 20:30 编辑

class ProducerConsumerDemo
{
public static void main(String[] args)
{
  Resource r = new Resource();
  Producer pro = new Producer(r);
  Consumer con = new Consumer(r);
  Thread t1 = new Thread(pro);
  Thread t2 = new Thread(pro);
  Thread t3 = new Thread(con);
  Thread t4 = new Thread(con);
  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{wait();}catch(Exception e){}//为什么在这里如果t1运行接受后唤醒的是t2而不是t3,t4
  this.name = name+"--"+count++;
  System.out.println(Thread.currentThread().getName()+"....生产者...."+this.name);
  flag = true;
  this.notifyAll();
}
public synchronized void out()
{
  while(!flag)try{wait();}catch(Exception e){}

  System.out.println(Thread.currentThread().getName()+"..消费者.."+this.name);
  flag = false;
  this.notifyAll();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(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在public synchronized void set(String name)如果t1运行结束后唤醒的是t2而不是t3,t4?
为什么使用if在blic synchronized void set(String name)如果t1运行结束后唤醒的有可能是t2,t3,t4?
为什么notifyAll();唤醒的是全部t2,t3,t4?

作者: 王章亚    时间: 2012-7-3 13:22

class ProducerConsumerDemo
{
public static void main(String[] args)
{
  Resource r = new Resource();
  Producer pro = new Producer(r);
  Consumer con = new Consumer(r);
  Thread t1 = new Thread(pro);
  Thread t2 = new Thread(pro);
  Thread t3 = new Thread(con);
  Thread t4 = new Thread(con);
  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{wait();}catch(Exception e){}//老师的视频里面有解释的,notify唤醒的是下一个等待的线程,t2就是下一个等待唤醒的线程
  this.name = name+"--"+count++;
  System.out.println(Thread.currentThread().getName()+"....生产者...."+this.name);
  flag = true;
  this.notifyAll();
}
public synchronized void out()
{
  while(!flag)try{wait();}catch(Exception e){}

  System.out.println(Thread.currentThread().getName()+"..消费者.."+this.name);
  flag = false;
  this.notifyAll();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(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();
  }
}
}
至于notifyAll是唤醒线程池里面所有等待的。兄弟不要纠结这个没有技术含量,知道它唤醒所有的就ok了!
作者: 郑庆伟    时间: 2012-7-3 13:29
我也在听就是有些不太明白  我在多听几遍。不行记下来回头再看。
作者: 郑庆伟    时间: 2012-7-3 13:31
我反应有点慢,有好多地方老师讲完,我还是不明白都是问了别人半天才弄明白,宿舍里面的几个学java的都被我问郁闷了,见到我都远远的,告诉我不要问我这么没有技术的问题,他们感觉是在问面试题。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2