黑马程序员技术交流社区

标题: 有耐心的同学来帮忙看看,代码有点长。 [打印本页]

作者: 马富林    时间: 2013-11-21 00:05
标题: 有耐心的同学来帮忙看看,代码有点长。
这是毕老师视频里讲关于多线程时的一个例子。
我有一个问题不明白。为什么在共用同一个锁的synchronized同步代码块中。一个线程在里面被wait()等待后。另一个线程可以进入这个代码块?
不是应该等被wait()的现象醒来从同步代码块中出去,第二个线程才可以进来吗?
  1. class ProDemo
  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);
  9.         Thread t2=new Thread(con);
  10.         t1.start();
  11.         t2.start();
  12.         }
  13. }
  14. class Resource
  15. {
  16.         private String name;
  17.         private int count=1;
  18.         private boolean flag=false;
  19.         public synchronized void set(String name)
  20.         {
  21.                 if(flag)
  22.                         try{wait();}catch(Exception e){}
  23.                 this.name=name+"-----"+count++;
  24.                 System.out.println(Thread.currentThread().getName()+".....生产者。。"+this.name);
  25.                 flag=true;
  26.                 this.notify();
  27.         }
  28.         public synchronized void out()
  29.         {
  30.                 if(!flag)
  31.                         try{wait();}catch(Exception e){}
  32.                 System.out.println(Thread.currentThread().getName()+".....消费者,,。。"+this.name);
  33.                 flag=false;
  34.                 this.notify();
  35.         }
  36. }
  37. class Producer implements Runnable
  38. {
  39.         private Resource res;
  40.         Producer(Resource res)
  41.         {
  42.         this.res=res;
  43.         }
  44.         public void run()
  45.         {
  46.         while(true)
  47.                 {
  48.                 res.set("+商品+");
  49.                 }
  50.         }
  51. }
  52. class Consumer implements Runnable
  53. {
  54.         private Resource res;
  55.         Consumer(Resource res)
  56.         {
  57.         this.res=res;
  58.         }
  59.         public void run()
  60.         {
  61.         while(true)
  62.                 {
  63.                 res.out();
  64.                 }
  65.         }
  66. }
复制代码

作者: qw无语    时间: 2013-11-21 00:19
wait()这个方法会失去锁和资格.
sleep()这个方法只会失去资格.
作者: hurryup    时间: 2013-11-21 00:34
因为针对此对象发出wait调用时,经过该对象的线程被冻结,并放弃对象锁,此时该线程丧失执行权,只有针对此对象发出notify或notifyall时,该线程才获得对象锁,进入等待锁定池,准备进入执行状态。
作者: 马富林    时间: 2013-11-21 01:26
hurryup 发表于 2013-11-21 00:34
因为针对此对象发出wait调用时,经过该对象的线程被冻结,并放弃对象锁,此时该线程丧失执行权,只有针对此 ...

那里面的线程被wait()后,对象锁又会回到这个被wait()线程进入之前的状态?从而可以让其他线程进入?




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