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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 崔龙飞 中级黑马   /  2013-7-20 16:24  /  1570 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 崔龙飞 于 2013-7-20 21:38 编辑
  1. class ThreadResource {
  2.         public static void main(String[] args) {
  3.                 Resource r = new Resource();
  4.                 new Thread(new Input(r)).start();
  5.                 new Thread(new Output(r)).start();
  6.         }
  7. }


  8. class Input implements Runnable{
  9.         private Resource r;
  10.         Input(Resource r) {
  11.                 this.r = r;
  12.         }
  13.         public void run() {
  14.                 int x = 0;
  15.                 while(true) {
  16.                         synchronized(r) {
  17.                                 if(r.flag)                // Res类里面flag已经定义为false,if(r.flag)里面的flag不也是false吗?
  18.                                                                 //那么在Input'线程第一次运行时,就应该等待,赋值操作也不会运行。
  19.                                                                 //老师说,flag第一次已经为false,所以就不需要等待,直接赋值。
  20.                                                                 //感觉这里好矛盾啊,实在搞不懂了,看了几片帖子都没有解释清楚。
  21.                                                                 //希望高手详细指点下flag的问题,多谢
  22.                                                 
  23.                                         try{r.wait();}catch(Exception e){}
  24.                                 if(x == 0) {
  25.                                         r.name = "Mike";
  26.                                         r.sex = "man";
  27.                                 } else {
  28.                                         r.name = "Lily";
  29.                                         r.sex = "woman";
  30.                                 }
  31.                                 x = (x + 1) % 2;
  32.                                 r.flag = true;
  33.                                 r.notify();
  34.                         }
  35.                 }
  36.         }
  37. }

  38. class Output implements Runnable {
  39.         private Resource r;
  40.         Output(Resource r) {
  41.                 this.r = r;
  42.         }
  43.         public void run() {
  44.                 while(true) {
  45.                         synchronized(r) {
  46.                                 if(!r.flag)                        
  47.                                         try{r.wait();}catch(Exception e){}
  48.                                 System.out.println(r.name + ": " + r.sex);
  49.                                 r.flag = false;
  50.                                 r.notify();
  51.                         }
  52.                 }
  53.         }
  54. }

  55. class Resource {
  56.         String name;
  57.         String sex;
  58.         boolean flag = false;
  59. }
复制代码

8 个回复

倒序浏览
flag标记的作用其实也就是让线程有规律的执行代码,input这个类,如果它的标记为true时,就让线程挂起,这个线程挂起的时候,当然会去执行另一个线程了,另一个线程!true当然是false了,所以就不会在挂了,直接执行代码就OK,执行完,把标记改了,在把对方唤醒,也许自己还能抢到执行权,但这时标记已经改过了,回头判断标记的时,这时!false,结果当然是true,这时就必须挂起的,如此循环。
回复 使用道具 举报
亲 你都说r.flage是false了 那if(r.flage)就是假,就直接跳过了呀,怎么会等待呢。你就理解成有没有就行。刚开始没有是false,写进去就有了true
回复 使用道具 举报
哪颗最亮的星星 发表于 2013-7-20 18:05
flag标记的作用其实也就是让线程有规律的执行代码,input这个类,如果它的标记为true时,就让线程挂起,这 ...

那也就是说if(flag)这里flag的值,和boolean flag = false没有关系,Input线程第一次运行时可以直接忽略。直到flag = true后,Input线程在唤醒Output线程后还持有执行权,这时再去判断flag,指已经值已经为true,所以就等待?我就是这点很迷糊,既然定义了flag为false,那为什么if(flag)里面的flag为什么不是false
回复 使用道具 举报
本帖最后由 罗广伟 于 2013-7-20 19:16 编辑
  1. if(x == 0) {
  2.                                         r.name = "Mike";
  3.                                         r.sex = "man";
  4.                                 } else {
  5.                                         r.name = "Lily";
  6.                                         r.sex = "woman";
  7.                                 }
  8. ///////////////////////
  9. if(!r.flag)                        
  10.                                         try{r.wait();}catch(Exception e){}
复制代码
回复 使用道具 举报
  1. if(x == 0) {
  2.                                         r.name = "Mike";
  3.                                         r.sex = "man";
  4.                                 } else {
  5.                                         r.name = "Lily";
  6.                                         r.sex = "woman";
  7.                                 }
  8. ///////////////////////
  9. if(!r.flag)                        
  10.                                         try{r.wait();}catch(Exception e){}
复制代码
你说的没错,flag初始值是false,如果input抢到资源则执行////上面代码进行赋值,如果output抢到资源就会执行///下面代码,等待,output等待时会放弃执行资格并释放锁此时input就能来获得执行资格。所以无论那个线程抢到资源结果都是先赋值

为什么发帖总是丢数据呢?害我重敲一边
回复 使用道具 举报
草貌路飞 发表于 2013-7-20 18:35
亲 你都说r.flage是false了 那if(r.flage)就是假,就直接跳过了呀,怎么会等待呢。你就理解成有没有就行。 ...

迷迷糊糊总算是懂了点,老师把我说晕菜了都,如果flag为false,r.flag就是false,也就是说满足了if(r.flag)的判断条件那么try{r.wait();}catch(Exception e){}作为它的执行体,就会被执行,Input线程一开始执行
就会等待。这么理解似乎也没有错啊。关键老师说false代表属性没有具体值,如果为false就要
进行赋值操作,赋值后改为true表示属性有值了。哎。。。我就崩溃了。你看看我这样改写的代码对不对
  1. class ThreadResource {
  2.         public static void main(String[] args) {
  3.                 Resource r = new Resource();
  4.                 new Thread(new Input(r)).start();
  5.                 new Thread(new Output(r)).start();
  6.         }
  7. }

  8. class Input implements Runnable{
  9.         private Resource r;
  10.         Input(Resource r) {
  11.                 this.r = r;
  12.         }
  13.         public void run() {
  14.                 int x = 0;
  15.                 while(true) {
  16.                         synchronized(r) {
  17.                                 if(r.flag == true)        //满足条件表示属性有值,需要输出,输入线程等待
  18.                                         try{r.wait();}catch(Exception e){}
  19.                                 if(x == 0) {
  20.                                         r.name = "Mike";
  21.                                         r.sex = "man";
  22.                                 } else {
  23.                                         r.name = "Lily";
  24.                                         r.sex = "woman";
  25.                                 }
  26.                                 x = (x + 1) % 2;
  27.                                 r.flag = true;
  28.                                 r.notify();
  29.                         }
  30.                 }
  31.         }
  32. }

  33. class Output implements Runnable {
  34.         private Resource r;
  35.         Output(Resource r) {
  36.                 this.r = r;
  37.         }
  38.         public void run() {
  39.                 while(true) {
  40.                         synchronized(r) {
  41.                                 if(r.flag == false)        //满足条件表示属性没值,需要赋值,输出线程等待               
  42.                                         try{r.wait();}catch(Exception e){}
  43.                                 System.out.println(r.name + ": " + r.sex);
  44.                                 r.flag = false;
  45.                                 r.notify();
  46.                         }
  47.                 }
  48.         }
  49. }

  50. class Resource {
  51.         String name;
  52.         String sex;
  53.         boolean flag = false;
  54. }
复制代码
回复 使用道具 举报
罗广伟 发表于 2013-7-20 19:17
你说的没错,flag初始值是false,如果input抢到资源则执行////上面代码进行赋值,如果output抢到资源就会执 ...

多谢,现在已经明白了
回复 使用道具 举报
崔龙飞 发表于 2013-7-20 20:24
迷迷糊糊总算是懂了点,老师把我说晕菜了都,如果flag为false,r.flag就是false,也就是说满足了if(r.fla ...

如果这样能便于你理解的话 是可以的
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马