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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 昝文萌 于 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>
复制代码

评分

参与人数 1技术分 +1 收起 理由
薛鹏鹏 + 1

查看全部评分

2 个回复

倒序浏览
LZ可以看一下API里关于wait()方法的说明,有这样一句:
“当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。”
这也是wait和sleep的重要区别,执行到wait的线程会把执行权释放给共用本锁的其他线程,而sleep不会。

评分

参与人数 2技术分 +1 黑马币 +10 收起 理由
昝文萌 + 10
EYE_SEE_YOU + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
受教了。当时看那句话时,没理解,最后反复思考,终于搞明白了!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马