黑马程序员技术交流社区

标题: 关于毕老师生产者消费者里的wait()用法的一些问题? [打印本页]

作者: 昝文萌    时间: 2013-8-25 10:20
标题: 关于毕老师生产者消费者里的wait()用法的一些问题?
本帖最后由 昝文萌 于 2013-8-26 08:10 编辑

在毕老师讲的生产者和消费者问题里,用了同步函数,生产者和消费者两个同步函数用的是同一把锁this,每个同步函数里都有等待唤醒机制,都用了wait(),但是如果当生产者进入生产者的同步函数后,执行了wait()方法,被阻塞后,它仍然在同步函数里,这样我认为消费者就进不去消费者的同步函数了,因为他们用的是同一把this锁,但是实际上消费者还可以进去进行消费,这个怎么理解!
  1. <p>class ProducerConsumerDemo
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 Resource r = new Resource();

  6.                 Producer pro = new Producer(r);
  7.                 Consumer con = new Consumer(r);

  8.                 Thread t1 = new Thread(pro);</p><p>Thread t2 = new Thread(con);
  9.   

  10. t1.start();
  11.                 t2.start();
  12.   
  13.         }
  14. }
  15. class Resource
  16. {
  17.         private String name;
  18.         private int count = 1;
  19.         private boolean flag = false;</p><p>
  20. public synchronized void set(String name)
  21.         {
  22. if(flag)
  23.                         try{this.wait();}catch(Exception e){}//<font color="#ff0000">假如生产者执行到这里被阻塞,但是生产者进入了同步函数,用的是ths这把锁。所以消费者应该就进不去消费者的同步函数了。但是实际上消费者还是可以进去的,怎么理解!</font>
  24.          this.name = name+"--"+count++;

  25.                 System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
  26.                 flag = true;
  27.                 this.notifyAll();
  28.         }

  29. public synchronized void out()//<font color="red">生产者被阻塞在生产者的同步函数里,但是消费者还可以进入消费者的同步函数,消费者用的也是this这把锁。</font>
  30.         {
  31. if(!flag)
  32.                         try{wait();}catch(Exception e){}
  33.          System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
  34.                 flag = false;
  35.                 this.notifyAll();
  36.         }
  37. }

  38. class Producer implements Runnable
  39. {
  40.         private Resource res;

  41.         Producer(Resource res)
  42.         {
  43.                 this.res = res;
  44.         }
  45.         public void run()
  46.         {
  47.                 while(true)
  48.                 {
  49.                         res.set("+商品+");
  50.                 }
  51.         }
  52. }

  53. class Consumer implements Runnable
  54. {
  55.         private Resource res;

  56.         Consumer(Resource res)
  57.         {
  58.                 this.res = res;
  59.         }
  60.         public void run()
  61.         {
  62.                 while(true)
  63.                 {
  64.                         res.out();
  65.                 }
  66.         }
  67. }</p>
复制代码

作者: yangjie    时间: 2013-8-25 10:49
LZ可以看一下API里关于wait()方法的说明,有这样一句:
“当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。”
这也是wait和sleep的重要区别,执行到wait的线程会把执行权释放给共用本锁的其他线程,而sleep不会。
作者: 昝文萌    时间: 2013-8-26 08:09
受教了。当时看那句话时,没理解,最后反复思考,终于搞明白了!





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