多线程代码练习

it2024-09-27  16

  《Java开发实战经典》中多线程的练习只有两道,为了恢复自己的编程能力,我特意做了做两道题。当我做完第一题的时候以为自己的感觉回来了,谁知道做了第二道题我才明白,自己对于多线程的“交通灯”模式根本不懂。

  这里的“交通灯”模式即是处理“生产者”与“消费者”之间同步协调的问题。哪知道一个看似简单的flag,就把我弄的晕头转向了……

  C++中有全局变量这个东西,可是,Java不能做到这个,Java是纯面向对象的语言,一切都是对象,所以……当我对书上的代码产生疑问时想自己写,一切调试无误之后,运行时Object.wait()却抛出一个异常……鸟懂……于是乎,只得去听从孔老夫子的教诲:“思而不学,则殆矣!”

  第二天看了看书,一直感觉这个代码很不合理,书上的例子是这样的:

代码  1  class  Info{     //  定义信息类  2       private  String name  =   " 李兴华 " ;      //  定义name属性  3       private  String content  =   " JAVA讲师 "   ;         //  定义content属性  4       private   boolean  flag  =   false  ;     //  设置标志位  5       public   synchronized   void  set(String name,String content){  6           if ( ! flag){  7               try {  8                   super .wait() ;  9              }  catch (InterruptedException e){ 10                  e.printStackTrace() ; 11              } 12          } 13           this .setName(name) ;     //  设置名称 14           try { 15              Thread.sleep( 300 ) ; 16          }  catch (InterruptedException e){ 17              e.printStackTrace() ; 18          } 19           this .setContent(content) ;     //  设置内容 20          flag  =   false  ;     //  改变标志位,表示可以取走 21           super .notify() ; 22      } 23       public   synchronized   void  get(){ 24           if (flag){ 25               try { 26                   super .wait() ; 27              }  catch (InterruptedException e){ 28                  e.printStackTrace() ; 29              } 30          } 31           try { 32              Thread.sleep( 300 ) ; 33          }  catch (InterruptedException e){ 34              e.printStackTrace() ; 35          } 36          System.out.println( this .getName()  +   37               "  -->  "   +   this .getContent()) ; 38          flag   =   true  ;     //  改变标志位,表示可以生产 39           super .notify() ; 40      } 41       public   void  setName(String name){ 42           this .name  =  name ; 43      } 44       public   void  setContent(String content){ 45           this .content  =  content ; 46      } 47       public  String getName(){ 48           return   this .name ; 49      } 50       public  String getContent(){ 51           return   this .content ; 52      } 53  }; 54  class  Producer  implements  Runnable{     //  通过Runnable实现多线程 55       private  Info info  =   null  ;         //  保存Info引用 56       public  Producer(Info info){ 57                   this .info  =  info ; 58              } 59               public   void  run(){ 60                   boolean  flag  =   false  ;     //  定义标记位 61           for ( int  i = 0 ;i < 50 ;i ++ ){ 62               if (flag){ 63                   this .info.set( " 李兴华 " , " JAVA讲师 " ) ;     //  设置名称 64                  flag  =   false  ; 65              } else { 66                   this .info.set( " mldn " , " www.mldnjava.cn " ) ;     //  设置名称 67                  flag  =   true  ; 68              } 69          } 70      } 71  }; 72  class  Consumer  implements  Runnable{ 73       private  Info info  =   null  ; 74       public  Consumer(Info info){ 75           this .info  =  info ; 76      } 77       public   void  run(){ 78           for ( int  i = 0 ;i < 50 ;i ++ ){ 79               this .info.get() ; 80          } 81      } 82  }; 83  public   class  ThreadCaseDemo03{ 84       public   static   void  main(String args[]){ 85          Info info  =   new  Info();     //  实例化Info对象 86          Producer pro  =   new  Producer(info) ;     //  生产者 87          Consumer con  =   new  Consumer(info) ;     //  消费者 88           new  Thread(pro).start() ; 89           new  Thread(con).start() ; 90      } 91  };    

 

 

  其中Info类做了太多的事,而这部分事本应该是由“生产者”和“消费者”类做的。

  联系中是说要把Info换成电脑。我简单点儿,就把电脑的属性抽象成一个编号Num,有了以下代码:

代码  1  class  Comp {  2       private   int  num  =   0 ;  3       static   boolean  flag  =   false ;  4       public   synchronized   void  setNum( int  num) {  5           if (flag) {                                 // 仅是在此处加入了等待与唤醒  6               try  {  7                   super .wait();  8              }  catch (InterruptedException e) {  9                  e.printStackTrace(); 10              } 11          } 12           this .num  =  num; 13          flag  =   true ; 14           super .notify(); 15      } 16       public   synchronized   int  getNum() { 17           if ( ! flag) {                                 // 同上 18               try  { 19                   super .wait(); 20              }  catch (InterruptedException e) { 21                  e.printStackTrace(); 22              } 23          } 24          flag  =   false ; 25           super .notify(); 26           return   this .num; 27      } 28  } 29  class  CompPro  implements  Runnable { 30       private  Comp comp  =   null ; 31       private   static   int  cout  =   0 ; 32       public  CompPro(Comp comp) { 33           this .comp  =  comp; 34      } 35       public   synchronized   void  run() { 36           int  i; 37           for (i = 0 ; i <= 50 ; i ++ ) { 38               try  { 39                  Thread.sleep( 100 );                 // 设置不同的睡眠时间以测试 40              }  catch (InterruptedException e) { 41                  e.printStackTrace(); 42              } 43              comp.setNum(cout); 44              cout ++ ; 45          } 46      } 47  } 48  class  CompSell  implements  Runnable { 49       private  Comp comp  =   null ; 50       public  CompSell(Comp comp) { 51           this .comp  =  comp; 52      } 53       public   synchronized   void  run() { 54           int  i; 55           for (i = 0 ; i <= 50 ; i ++ ) { 56               try  { 57                  Thread.sleep( 15 );                 // 设置不同的睡眠时间以测试 58              }  catch (InterruptedException e) { 59                  e.printStackTrace(); 60              } 61              System.out.println(comp.getNum()); 62          } 63      } 64  } 65  public   class  Comps { 66       public   static   void  main(String[] args) { 67          Comp c  =   new  Comp(); 68          CompPro pro  =   new  CompPro(c); 69          CompSell sell  =   new  CompSell(c); 70           new  Thread(pro).start(); 71           new  Thread(sell).start(); 72      } 73  }

 

 

  调试了很久,终于成功了,其中大家要是真看了代码的话,对于flag的设置一定要小心,起始与变换……

  就是这样了。 

 

 

转载于:https://www.cnblogs.com/mooner-hw/archive/2011/01/29/1947322.html

相关资源:java基础多线程练习题(1)
最新回复(0)