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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

夏立元

初级黑马

  • 黑马币:

  • 帖子:

  • 精华:

本帖最后由 夏立元 于 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. }
复制代码
可是优化完运行结果不是交替输出了,想不明白。这是为什么啊?



评分

参与人数 1技术分 +1 收起 理由
袁錦泰 + 1 我曾经也出现过这样的情况,是判断出的问题..

查看全部评分

2 个回复

倒序浏览
本帖最后由 罗文杰 于 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-6 18:31
第二段两个方法中  if else语句的问题  直接写else中的内容,把else去掉。
  if(!flag)
  {

可是我优化前的程序也用的if else 为什么运行结果却是正确的啊 ?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马