黑马程序员技术交流社区

标题: 【求助】大早就不通,闷啊,多线程通信问题 [打印本页]

作者: 黄奕豪    时间: 2012-5-21 06:09
标题: 【求助】大早就不通,闷啊,多线程通信问题
本帖最后由 黄奕豪 于 2012-5-21 06:10 编辑

由于敲着习惯了,打了if就顺着打个else,所以打出问题来了,仔细跟毕老师的代码对比,依瓢画葫芦的,终于能实现了!!可是想不通第30行的代码多了个else怎么就不行!!~~~~~大清早的!!愁啊!!!
  1. /*
  2.         毕老师基础教程-第12天-3(多线程间通信-代码优化)
  3.         需求:
  4.                 存储个人信息和打印个人信息的程序,一个线程存信息,一个线程打印信息,存完就打印,打印完就存!
  5. */

  6. class Info  //共享资源个人信息类
  7. {
  8.         private String name;
  9.         private String sex;
  10.         private boolean flag = true;
  11.         public synchronized void set(String name,String sex)
  12.         {
  13.                 if(!flag)
  14.                 {
  15.                         try        {this.wait();}catch (InterruptedException iex){}
  16.                 }
  17.                 this.name=name;
  18.                 this.sex = sex;
  19.                 flag=false;
  20.                 this.notify();
  21.         }

  22.         public synchronized void print()
  23.         {
  24.                 if(flag)
  25.                 {
  26.                         try        {this.wait();}catch (InterruptedException iex){}
  27.                 }
  28.                 //为什么我在这里加上了个else打印出来的结果就是无序的呢?注释掉就可以轮流打印了!!想不明白~~~~~
  29.                 //else
  30.                         System.out.println(name+"-----------"+sex);
  31.                 flag = true;                        
  32.                 this.notify();
  33.         }
  34. }

  35. //负责输入的类
  36. class Input implements Runnable
  37. {
  38.         private Info c;
  39.         public Input(Info c)
  40.         {
  41.                 this.c = c;
  42.         }
  43.         public void run()
  44.         {
  45.                 int flag=0;
  46.                 while(true)
  47.                 {
  48.                         if(flag==0)
  49.                                 c.set("wangwu","man");
  50.                         else
  51.                                 c.set("李四","女");
  52.                         flag=(flag+1)%2;
  53.                 }
  54.                
  55.         }        
  56. }

  57. //负责打印的类
  58. class Out implements Runnable
  59. {
  60.         private Info c;
  61.         public Out(Info c)
  62.         {
  63.                 this.c = c;
  64.         }
  65.         public void run()
  66.         {
  67.                 while(true)
  68.                 {
  69.                         c.print();
  70.                 }
  71.         }
  72. }

  73. class  ThreadCommunicationDemo2
  74. {
  75.         public static void main(String[] args)
  76.         {
  77.                 Info c=new Info();
  78.                 new Thread(new Input(c)).start();
  79.                 new Thread(new Out(c)).start();
  80.         }
  81. }
复制代码

作者: 8161776    时间: 2012-5-21 07:42
  1.         public synchronized void print()
  2.         {
  3.                 if(flag)
  4.                 {
  5.                         try        {this.wait();}catch (InterruptedException iex){}
  6.                 }
  7.                 //为什么我在这里加上了个else打印出来的结果就是无序的呢?注释掉就可以轮流打印了!!想不明白~~~~~

  8. //因为你加上else以后只有flag是false的时候才能执行到,不加else的话 无论flag是true还是false都能执行到的!!

  9.                 //else
  10.                         System.out.println(name+"-----------"+sex);
  11.                 flag = true;                        
  12.                 this.notify();
  13.         }
复制代码

作者: 贾旭    时间: 2012-5-21 10:41
  1.         public synchronized void print()
  2.         {
  3.                 if(flag)
  4.                 {
  5.                         try        {this.wait();}catch (InterruptedException iex){}
  6.                 }
  7.                 //为什么我在这里加上了个else打印出来的结果就是无序的呢?注释掉就可以轮流打印了!!想不明白~~~~~
  8.                 //else

  9.                         System.out.println(name+"-----------"+sex);
  10.                 flag = true;                        
  11.                 this.notify();
  12.         }
  13. }
复制代码
flag是标记,为true时就将当前线程置为wait状态,等待另一个线程唤醒。
不加else时,如果flag为真,则当前线程等待唤醒,被唤醒后打印。
加上else后,只有flag为假的时候才能打印。
也就是说,你加上else后,当前线程Wait被唤醒后,原本可以打印,但是因为了加了else,就只能在flag为假的时候打印了。



作者: 黄奕豪    时间: 2012-5-21 18:10
贾旭 发表于 2012-5-21 10:41
flag是标记,为true时就将当前线程置为wait状态,等待另一个线程唤醒。
不加else时,如果flag为真,则当前 ...

好像明白了!!当wait()被唤醒后,因为后面有else~,前面wait()之前因为判断过if了!!所以直接跳过打印!!是这样的么?谢谢啊!




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