黑马程序员技术交流社区

标题: 线程间通信示例码优化出现的一个问题 [打印本页]

作者: 夏立元    时间: 2012-6-6 18:09
标题: 线程间通信示例码优化出现的一个问题
本帖最后由 夏立元 于 2012-6-6 18:12 编辑

基础视频中多线程通信的一个示例:两个线程分别对资源的成员变量(name和sex)持续进行写入和输出,运行结果是交替输出“张三....男”和“LiLi...female”。
优化前代码:
  1. class Res
  2. {
  3.        String name;
  4.        String sex;
  5.        boolean flag=true; ............................................ flag控制写入和输出的交替进行
  6. }
  7. class Input implements Runnable...............................写入类
  8. {
  9.        private Res s;
  10.        Input(Res s)
  11.       {
  12.          this.s=s;
  13.       }
  14.        public void run()
  15.      {
  16.         boolean b=true;.............................................b 控制男女的交替写入
  17.         while(true)
  18.            {
  19.             synchronized(s)
  20.               {
  21.                 if(s.flag)
  22.                    {
  23.                       if(b)
  24.                        {
  25.                           s.name="张三";
  26.                           s.sex="......................男";
  27.                           b=false;
  28.                        }
  29.                       else
  30.                       {
  31.                          s.name="LiLi";
  32.                          s.sex="......................female";
  33.                          b=true;
  34.                      }
  35.                       s.flag=false;
  36.                       s.notify();
  37.                   }
  38.                else
  39.                 {
  40.                      try{this.wait();}catch(Exception e){}
  41.                 }
  42.              }
  43.          }
  44.       }
  45. }
  46. class Output implements Runnable .............................输出类
  47. {
  48.         private Res s;
  49.         Output(Res s)
  50.        {
  51.         this.s=s;
  52.        }
  53.         public void run()
  54.       {
  55.       while(true)
  56.            {
  57.             synchronized(s)
  58.               {
  59.                 if(!s.flag)
  60.                   {
  61.                     System.out.println(s.name+"..........."+s.sex);
  62.                     s.flag=true ;
  63.                     s.notify();
  64.                   }
  65.                else
  66.                  {
  67.                    try
  68.                    {
  69.                     s.wait();
  70.                    }
  71.                    catch (Exception e)
  72.                   {
  73.                   }
  74.                 }
  75.              }
  76.           }
  77.        }
  78. }
  79. class InputOutput
  80. {
  81.        public static void main(String[] args)
  82.     {
  83.       Res s=new Res();
  84.       new Thread(new Input(s)).start();
  85.       new Thread(new Output(s)).start();
  86.     }
  87. }
复制代码
然后,对代码进行优化,主要是将写入和输出作为方法放在Res类中,同步也在Res类中完成,优化后代码:

  1. class Res
  2. {
  3.   private String name;
  4.   private String sex;
  5.   private boolean flag=true;
  6.   public synchronized void set(String name,String sex)
  7. {
  8.    if(flag)
  9.   {
  10.    this.name=name;
  11.    this.sex=sex;
  12.    flag=false;
  13.    this.notify();
  14.    }
  15.    else
  16.   {
  17.    try{this.wait();}catch(Exception e){}
  18.    }  
  19.   }
  20.   public synchronized void put()
  21. {
  22.     if(!flag)
  23.   {
  24.                 System.out.println(name+"........."+sex);
  25.        flag=true;
  26.     this.notify();
  27.   }     
  28.   else
  29.   {
  30.     try{this.wait();}catch(Exception e){}
  31.   }        
  32.   }
  33. }
  34. class Input implements Runnable
  35. {
  36. private Res s;
  37. Input(Res s)
  38. {
  39.   this.s=s;
  40. }
  41. public void run()
  42. {
  43.   boolean b=true;
  44.   while(true)
  45.   {
  46.              if(b)
  47.        {
  48.     s.set("张三","                 男");
  49.     b=false;
  50.     }
  51.    else
  52.    {
  53.         s.set("LiLi","                       female");
  54.      b=true;
  55.    }      
  56.   }
  57. }
  58. }
  59. class Output implements Runnable
  60. {
  61. private Res s;
  62. Output(Res s)
  63. {
  64.   this.s=s;
  65. }
  66. public void run()
  67. {
  68.    while(true)
  69.      {      
  70.                  s.put();
  71.    }
  72. }
  73. }
  74. class Demo
  75. {
  76. public static void main(String[] args)
  77. {
  78.    Res s=new Res();
  79.    new Thread(new Input(s)).start();
  80.    new Thread(new Output(s)).start();
  81. }
  82. }
复制代码
可是优化完运行结果不是交替输出了,想不明白。这是为什么啊?




作者: 罗文杰    时间: 2012-6-6 18:31
本帖最后由 罗文杰 于 2012-6-6 18:35 编辑

第二段两个方法中  if else语句的问题  直接写else中的内容,把else去掉。
  if(!flag)
  {
                System.out.println(name+"........."+sex);
       flag=true;
    this.notify();
  }     
  //else
  //{
    try{this.wait();}catch(Exception e){}
  //}      

如果有else的话 当if内容为真的时候就不会执行下面的wait语句,这时会出现两个线程都不会wait的情况,就不会逐条输出了,加上注释后就可以达到目的了。
作者: 夏立元    时间: 2012-6-7 17:39
罗文杰 发表于 2012-6-6 18:31
第二段两个方法中  if else语句的问题  直接写else中的内容,把else去掉。
  if(!flag)
  {

可是我优化前的程序也用的if else 为什么运行结果却是正确的啊 ?




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