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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 罗广伟 中级黑马   /  2013-6-7 11:17  /  2110 人查看  /  12 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 罗广伟 于 2013-6-7 15:30 编辑

//等待唤醒机制代码
  1. class Res
  2. {
  3.         private String name;
  4.         private String sex;
  5.         private boolean flag = false;

  6.         public synchronized void set(String name,String sex)
  7.         {
  8.                 if(flag)
  9.                         try{this.wait();}catch(Exception e){}
  10.                 this.name = name;
  11.                
  12.                 this.sex = sex;
  13.                 flag = true;
  14.                 this.notify();
  15.         }
  16.         public synchronized void out()
  17.         {
  18.                 if(!flag)
  19.                         try{this.wait();}catch(Exception e){}
  20.                 System.out.println(name+"........"+sex);
  21.                 flag = false;
  22.                 this.notify();
  23.         }
  24. }

  25. class Input implements Runnable
  26. {
  27.         private Res r ;
  28.         Input(Res r)
  29.         {
  30.                 this.r = r;
  31.         }
  32.         public void run()
  33.         {
  34.                 int x = 0;
  35.                 while(true)
  36.                 {
  37.                         if(x==0)                                
  38.                                 r.set("mike","man");                                
  39.                         else        
  40.                                 r.set("丽丽","女女女女女");                                
  41.                         x = (x+1)%2;
  42.                 }
  43.         }
  44. }

  45. class Output implements Runnable
  46. {
  47.         private Res r ;
  48.         
  49.         Output(Res r)
  50.         {
  51.                 this.r = r;
  52.         }
  53.         public void run()
  54.         {
  55.                 while(true)
  56.                 {
  57.                         r.out();
  58.                 }
  59.         }
  60. }


  61. class  InputOutputDemo2
  62. {
  63.         public static void main(String[] args)
  64.         {
  65.                 Res r = new Res();
  66.                 Input in = new Input(r);
  67.                 Output out = new Output(r);

  68.                 Thread t1 = new Thread(in);
  69.                 Thread t2 = new Thread(out);

  70.                 t1.start();
  71.                 t2.start();
  72.         }
  73. }
复制代码
//问题:Res类中,set方法和out方法持有的锁是this,是同一个锁,那么当set方法出现等待时,因为持有this锁,out方法是无法运行的,那么程序也就死了.
//可是事实是一个等待另一个就运行,为什么呢?

评分

参与人数 1技术分 +1 收起 理由
刘凯 + 1

查看全部评分

12 个回复

倒序浏览
排版下先
回复 使用道具 举报
代码没法看啊,你插入代码,别直接复制粘贴
回复 使用道具 举报
hx32 发表于 2013-6-7 11:20
代码没法看啊,你插入代码,别直接复制粘贴

刚改过了,麻烦看一下
回复 使用道具 举报
罗广伟 发表于 2013-6-7 11:21
刚改过了,麻烦看一下

我不会:loveliness:还没学到哪里呢
回复 使用道具 举报
hx32 发表于 2013-6-7 11:24
我不会还没学到哪里呢

哦,好好学吧:)
回复 使用道具 举报
wait 和 notify 等待和唤醒的是同一个锁  每次判断后 根据你设置的开关 flag 判定是否该线程进入 等待状态 同时唤醒 同锁下等待的其他线程  两个线程交替执行  保证不死锁    如果线程多了就不好整了
回复 使用道具 举报
杨彬 发表于 2013-6-7 12:20
wait 和 notify 等待和唤醒的是同一个锁  每次判断后 根据你设置的开关 flag 判定是否该线程进入 等待状态  ...
  1. public synchronized void set(String name,String sex)
  2.         {
  3.                 if(flag)
  4.                         try{this.wait();}catch(Exception e){}
  5.                 this.name = name;
  6.                
  7.                 this.sex = sex;
  8.                 flag = true;
  9.                 this.notify();
  10.         }
  11.         public synchronized void out()
  12.         {
  13.                 if(!flag)
  14.                         try{this.wait();}catch(Exception e){}
  15.                 System.out.println(name+"........"+sex);
  16.                 flag = false;
  17.                 this.notify();
  18.         }
复制代码
如果程序执行到set方法wait方法时另一个线程执行out方法,这时执行set方法的线程不是持有this锁吗,那么执行out方法的线程不是不能读out方法里面的内容吗?这样程序就死了。
回复 使用道具 举报
LZ的单对单的生产-消费模式执行流程:(1)flg=false:
回复 使用道具 举报
发错了,不好意思。重发!
LZ的单对单的生产-消费模式执行流程:
(1)flg=false: 消费者(out)等待,锁对象的wait方法释放锁;
(2) 生产者获得锁,生产产品(set)后,产品“入库”(flg=true),然后唤醒消费者,这时下次即使生产者再次获得了锁,由于“仓库已满”,生产者依然会等待,直到消费者取走产品
(3)消费者获得锁,消费产品(out)后,仓库空了(flg=false),然后唤醒消生产者,与(2)类似,消费者下次即使再次获得了锁,由于“仓库已空”消费者依然会等待,直到生产者取生产完产品;
notify和wait读会释放锁,wait释放锁后会等待,直到其他持有同样锁的线程执行notify(或者notifyAll)方法。线程执行唤醒方法后,仍可以继续竞争锁。希望你能明白,另外你继续尝试多对多的生产消费模式,这里set out方法里面用if语句是会有问题的。希望这个解释能对你有帮助哈!
回复 使用道具 举报
kaka小明 发表于 2013-6-7 14:12
发错了,不好意思。重发!
LZ的单对单的生产-消费模式执行流程:
(1)flg=false: 消费者(out)等待,锁对象 ...

明白了,多谢。就是wait(),sleep(),这些线程冻结状态时就会释放锁。我理解对吧?
回复 使用道具 举报
sleep不释放锁!
回复 使用道具 举报

哦,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马