A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郑庆伟 中级黑马   /  2012-7-3 13:16  /  1589 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郑庆伟 于 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?

3 个回复

倒序浏览

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了!
回复 使用道具 举报
我也在听就是有些不太明白  我在多听几遍。不行记下来回头再看。
回复 使用道具 举报
我反应有点慢,有好多地方老师讲完,我还是不明白都是问了别人半天才弄明白,宿舍里面的几个学java的都被我问郁闷了,见到我都远远的,告诉我不要问我这么没有技术的问题,他们感觉是在问面试题。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马