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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© tc庄稼汉 中级黑马   /  2014-8-2 21:46  /  866 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. class Resource
  2. {
  3.         private String name;
  4.         private int count=1;

  5.         private boolean flag=false;

  6.         //注释一
  7.         public synchronized void set(String name)//①t1拥有执行权 t2等待->②执行到notify()唤醒t2,t1判断标识后执行wait(),等待->③t2开始执行
  8.         {
  9.                 if(flag)
  10.                         try
  11.                         {
  12.                                 this.wait();
  13.                         }
  14.                         catch (InterruptedException e)
  15.                         {
  16.                         }
  17.                         this.name=name+count;
  18.                         count++;
  19.                         System.out.println(Thread.currentThread().getName()+"...生产者"+this.name);
  20.                         flag=true;
  21.                         this.notify();
  22.         }
  23.         public synchronized void out()//t3等待 t4等待
  24.         {
  25.                 if(!flag)
  26.                         try
  27.                         {
  28.                                 this.wati();
  29.                         }
  30.                         catch (InterruptedException e)
  31.                         {
  32.                         }
  33.                 System.out.println(Thread.currentThread().getName+"...消费者"+this.name);
  34.                 flag=false;
  35.                 this.notify();
  36.         }
  37. }

  38. class Producer implements Runnable
  39. {
  40.         private Resource r;
  41.         producer(Resource r)
  42.         {
  43.                 this.r=r;
  44.         }
  45.         public void run()
  46.         {
  47.                 while(true)
  48.                 {
  49.                         r.set("面包");
  50.                 }
  51.         }
  52. }
  53. class Consumer implements Runnable
  54. {
  55.         private Resource r;
  56.         consumer(Resource r)
  57.         {
  58.                 this.r=r;
  59.         }
  60.         public void run()
  61.         {
  62.                 while(true)
  63.                 {
  64.                         r.out();
  65.                 }
  66.         }
  67. }
  68. class  ThreadDemo
  69. {
  70.         public static void main(String[] args)
  71.         {
  72.                 Resource r=new Resource();
  73.                 Producer pro=new Producer(r);
  74.                 Consumer con=new Consumer(r);


  75.                 Thread t1=new Thread(pro);
  76.                 Thread t2=new Thread(pro);

  77.                 Thread t3=new Thread(con);
  78.                 Thread t4=new Thread(con);

  79.                 t1.start();
  80.                 t2.start();
  81.                 t3.start();
  82.                 t4.start();


  83.         }
  84. }
复制代码
毕老师讲解多生产多消费时的代码事例


如上述代码注释一:
①t1拥有执行权,t2等待,t1执行同步代码,输出:Thread-0......生产者....面包2499,更改flag=true,执行notify()唤醒t2;
②此时t1仍然持有锁对象以及执行权,t1继续执行同步代码,首先进行if判断,flag为true,执行wait(),t1释放锁对象,处于等待状态;
③t2持有锁,开始执行同步代码。
疑点:此时flag仍然为true,为什么t2不需要进行if判断,可以继续执行下面的代码,
         输出: Thread-1......生产者.....2500

5 个回复

倒序浏览
等待之前不是已经执行过if语句了么,如果你想唤醒之后再判断一次,那就要把if改成while
回复 使用道具 举报
fantacyleo 发表于 2014-8-2 21:52
等待之前不是已经执行过if语句了么,如果你想唤醒之后再判断一次,那就要把if改成while ...

t2获得执行权后,难道不是从同步代码块的起始位置开始执行么。多线程不是只是操作了共享资源,而操作共享资源的代码会被加载到单独每个线程栈里么。
回复 使用道具 举报
tc庄稼汉 发表于 2014-8-2 22:02
t2获得执行权后,难道不是从同步代码块的起始位置开始执行么。多线程不是只是操作了共享资源,而操作共享 ...

第一次是,可你说的是t2等待后又被唤醒,那当然就是从等待处开始执行啦
回复 使用道具 举报
fantacyleo 发表于 2014-8-2 22:05
第一次是,可你说的是t2等待后又被唤醒,那当然就是从等待处开始执行啦

恩 ,明白了! 也就是说t2线程从上一次停止的地方开始执行。你的意思是这几个线程wait之后,再一次执行时都不需要进行判断了吧。
回复 使用道具 举报
if一般指判断一次,while判断多次的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马