黑马程序猿——12,多线程(2)

------<ahref="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

              黑马程序猿——12,多线程(2)

 

//线程之间的通信
//就是多个线程操作同一个资源,操作动作不同
//举一个样例:一堆资源(名字,性别),一个线程输入,一个线程输出打印
 
class  Person
{
         String  name;
         String  sex;
}
 
class   Shuru  implements  Runnable            
{
     private  Person  p;
           Shuru( Person p   )
           {
               this.p=p;
           }
           public  void  run()
           {
                     int x= 0;
                     while(true)//特别说明:由于 while (true)这句话的关系。最后要按Ctrl+c按键才停下虚拟机,否则会耗费非常多资源)        
                     {
            if(x==0)
                              {
               p.name="张三";
                          p.sex="男性";
                              }
                              else
                              {
               p.name="李四";
                          p.sex="女性";
                              }
                              x=(x+1)%2;
                     }
           }
}
class  Shuchu  implements  Runnable
{
           private Person  p;
           Shuchu( Person  p   )
           {
               this.p=p;
           }
            public  void  run()
           {
               while(true)
                     { 
                              System.out.println(p.name+"-----"+p.sex);
                     }
           }
 
}
 
class Xctx
{
         public  static  void  main(String[] args)
         {
                   Person  p=new Person();
 
                   Shuru  b1=new Shuru(p);
                   Shuchu  b2=new Shuchu(p);
 
                   Thread  c1=new Thread(b1);
                   Thread  c2=new Thread(b2);
 
                   c1.start();
             c2.start();
                   System.out.println("HelloWorld!");
         }
}
 
/*
依照一般的思路。准确的打印应该是张三相应男性,李四相应女性的
但是编译执行的结果例如以下。出了问题:
Hello World!
李四-----男性
李四-----男性
李四-----女性
李四-----男性
张三-----女性
张三-----女性
李四-----男性
李四-----男性
张三-----男性
张三-----女性
张三-----男性
张三-----男性
李四-----男性
张三-----男性
李四-----女性
李四-----男性
张三-----男性
李四-----女性
张三-----女性
李四-----女性
李四-----男性
 
 
出问题的解决办法是:输入线程在输入信息的同一时候输出线程也在打印,
那么非常有可能在输入信息输入到一半的时候。就被输出线程打印出去了。
那么打印出去的就是部分更新数据部分旧数据,这就相应不上了
*/

——————分析——————

//为了解决这样的问题,我们还是能够用同步代码块来解决
/*
原理就是输入线程与输出线程都是对同一个对象操作。仅仅只是操作过程不一样
那么使用同步代码块,让两个使用同一个锁,这样就限制了在某一个时刻仅仅能够有一个线程对对象进行操作
等这个线程操作完之后下一个线程才干够对对象进行操作
确保了打印出来的对象信息的更新是完整
*/
 
class  Person
{
         String  name;
         String  sex;
         static  Object obj=new Object();
}
 
class   Shuru  implements Runnable            
{
     private  Person  p;
           Shuru( Person p   )
           {
               this.p=p;
           }
           public  void run()
           {
                     int x= 0;
                     while(true)//特别说明:由于 while (true)这句话的关系,最后要按Ctrl+c按键才停下虚拟机。否则会耗费非常多资源)
        
                     {
                              synchronized(Person.obj)//用的锁是obj
                              {
                if(x==0)
                                {
                  p.name="张三";
                             p.sex="男性";
                                }
                                else
                                {
                   p.name="李四";
                              p.sex="女性";
                                }
                                x=(x+1)%2;
                             }
                     }
           }
 
 
}
class   Shuchu  implements  Runnable
{
           private  Person   p;
           Shuchu( Person  p   )
           {
               this.p=p;
           }
            public void run()
           {
               while(true)
                     { 
                              synchronized(Person.obj)//用的锁是obj
                              {
                             System.out.println(p.name+"-----"+p.sex);
                              }
                     }
           }
 
}
 
class  Xctx2
{
         public  static  void  main(String[] args)
         {
                   Person  p=new Person();
 
                   Shuru  b1=new Shuru(p);
                   Shuchu  b2=new Shuchu(p);
 
                   Thread  c1=new Thread(b1);
                   Thread  c2=new Thread(b2);
 
                   c1.start();
             c2.start();
                   System.out.println("HelloWorld!");
         }
}

——————分析——————

</pre><pre name="code" class="java">//线程通信中的等待唤醒机制的样例
 
/*
等待唤醒机制,简单的说法就是
用一个标示(通常是Boolean型的变量)
true标记输入线程操作,而false标记输出线程操作
输入线程操作时候,输出线程冻结状态
输出线程操作时候。输入线程冻结状态
这样来保证输出结果的准确性
这就须要用到wait()和notify()  或者是notifyAll()
*/
class  Person
{
         String  name;
         String  sex;
         static  Object obj=new Object();
         boolean  bs=true;//设定一个标示
}
 
class   Shuru  implements Runnable            
{
     private  Person  p;
           Shuru( Person p   )
           {
               this.p=p;//接收一个Person类的对象,就指向该对象。该写法更加方便
           }
           public  void  run()
           {
                     int x= 0;
                     while(true)
//特别说明:由于 while (true)这句话的关系,最后要按Ctrl+c按键才停下虚拟机。否则会耗费非常多资源)
        
                     {
                              synchronized(Person.obj)//用的锁是obj
                              {
                if(!p.bs)
                                       {
                                               try{Person.obj.wait();}catch(Exception e){}
                                       }
                                               //wait()方法能够冻结线程,该方法是定义在Object类的
                                               /*
                               这里为什么不直接用wait()呢?
                               由于wait()方法会抛出一个异常所以要用try...catch
                               为什么这里还要在wait前面加上Person.obj这个锁呢?
                               由于这样的写法:锁.wait();   -----表示持有该锁的线程要陷入沉睡。
                               也是由于这个原因,wait()方法必须在同步中才干够用,而notify() 
                               和notifyAll()也是由于以上原因在同步中才干够用。
                               其写法也是:  锁.notify();或者是  锁.notifyAll();
                  
                                               */
                if(x==0)
                                {
                  p.name="张三";
                             p.sex="男性";
                                }
                                else
                                {
                  p.name="李四";
                              p.sex="女性";
                                }
                                x=(x+1)%2;
                Person.obj.notify();
                                     /*
                                     陷入沉睡的线程都会被扔进线程池
                                     notify()方法功能是唤醒在在线程池中头一个沉睡的线程
                                     而notifyAll()方法则是唤醒全部沉睡的线程
                                     */
                 p.bs=false;
                             }
                     }
           }
 
 
}
class   Shuchu  implements  Runnable
{
           private  Person   p;
           Shuchu( Person  p   )
           {
               this.p=p;
           }
            public  void  run()
           {
               while(true)
                     { 
                              synchronized(Person.obj)//用的锁是obj
                              {
                                       if(p.bs)
                                       {
                                                 try{Person.obj.wait();} catch(Exception e){}
                                       }
                                    
                   
                                 System.out.println(p.name+"-----"+p.sex);
                                       Person.obj.notify();
                  p.bs=true;
                              }
                     }
           }
 
}
 
class Xctx3
{
         public  static void main(String[] args)
         {
                   Person  p=new Person();
 
                   Shuru  b1=new Shuru(p);
                   Shuchu  b2=new Shuchu(p);
 
                   Thread  c1=new Thread(b1);
                   Thread  c2=new Thread(b2);
 
                   c1.start();
             c2.start();
                   System.out.println("HelloWorld!");
         }
}
/*
以上程序编译执行结果是:
Hello World!
张三-----男性
李四-----女性
张三-----男性
李四-----女性
张三-----男性
李四-----女性
张三-----男性
李四-----女性
张三-----男性
李四-----女性
张三-----男性
李四-----女性
张三-----男性
李四-----女性
 
*/

 


补充:对于非静态的synchronized方法,其锁默觉得this

           对于静态的synchronized方法。其锁默认:为该方法所在类的类名.class     

         对于同步代码块,其锁就是括号内的东西。

——————切割线————————

//下面是代码优化之后的程序,更加简洁明了
class  Person
{
         private  String  name;
         private  String  sex;
        
         private  boolean  bs=true;//设定一个标示
         public  synchronized  void  set( String name,String  sex   )//写入资料的方法
         {
                   if(!bs)
                   {       
                            try{this.wait();}catch(Exception e){}
                   }
                                    
              this.name=name;
                    this.sex=sex;
                    bs=false;
                     this.notify();
         }
         public  synchronized  void  out()//打印资料的方法
         {
         if(bs)
                   {       
                            try{this.wait();}catch(Exception e){}
                   }
            System.out.println("输出的是----"+name+"---"+sex);
                    bs=true;
                    this.notify();
         }
}
 
class   Shuru  implements  Runnable            
{
     private  Person  p;
           Shuru( Person p   )
           {
               this.p=p;
           }
           public  void  run()
           {
                     int x= 0;
                     while(true)//特别说明:由于 while (true)这句话的关系,最后要按Ctrl+c按键才停下虚拟机。否则会耗费非常多资源)
        
                     {
          
               if(x==0)
                   p.set("张三","男性");
                                else
                    p.set("李四","女性");
                              
                                     x=(x+1)%2;
                           
                     }
           }
 
 
}
class  Shuchu  implements  Runnable
{
           private Person  p;
           Shuchu( Person  p   )
           {
               this.p=p;
           }
            public void run()
           {
               while(true)
                     {
                            p.out();
                     }
           }
 
}
 
class  Xctx4
{
         public  static  void  main(String[] args)
         {
                   Person  p=new Person();
 
                   newThread(new Shuru(p)).start();
             new Thread(new Shuchu(p)).start();
 
                   System.out.println("HelloWorld!");
/*
                   Shuru  b1=new Shuru(p);
                   Shuchu  b2=new Shuchu(p);
 
                   Thread  c1=new Thread(b1);
                   Thread  c2=new Thread(b2);
 
                   c1.start();
             c2.start();
                   System.out.println("HelloWorld!");
*/
         }
}

————————切割线——————

/*
多线程的常见生活样例
有多个生产者生产食品,有多个消费者消化食品
每生产一个食品就消费一个食品
*/
 
class  Shipin
{
         private  int  sp=0;
         private   boolean   f=true;
         public  synchronized  void  shengchang(  )
         {
                   while(true)
                   {
        
                    while(f==false)//注意这里用的是while所以每次线程从冻结状态醒来都要检查一次f是否是false
                       try{this.wait();} catch(Exception e){}
        sp++;
              System.out.println("生产者"+Thread.currentThread().getName()+"----"+sp);
                  
                    f=false;
                    this.notifyAll();
                    /*
                       这里用notifyAll()方法就是为了让全部沉睡的线程醒来
          既唤醒了生产者又唤醒了消费者
          此时假设f=true那么因为之前的while作用。消费者即使是得到权限(锁)也不能运行仅仅能冻结,所以仅仅有一个生产者能够得到权限运行。
         此时假设是f=false那么因为之前的while作用,生产者即使是得到权限(锁)也不能运行仅仅能冻结所以仅仅有一个消费者能够得到权限运行。
                    */
                   }
                  
         }
         public  synchronized  void  xiaofei(   )
         {
                   while(true)
                   {
                     while(f==true)
                       try{this.wait();} catch(Exception e){} 
 
                System.out.println("消费者"+Thread.currentThread().getName()+"----"+sp);
                  
                      f=true;
                      this.notifyAll();
                   }
         }
}
class  Shengchangzhe  implements  Runnable
{
         private  Shipin   a ;
         Shengchangzhe(Shipin   a)
         {
             this.a=a;
         }
   public void run()
         {
              a.shengchang();     
         }
}
 
class  Xiaofeizhe  implements  Runnable
{
   private  Shipin   a ;
         Xiaofeizhe(Shipin   a)
         {
             this.a=a;
         }
   public  void run()
         {
              a.xiaofei();     
         }
}
class   Xctx5
{
         public  static  void  main(String[] args)
         {
                   Shipin  a=new Shipin();
 
                   Shengchangzhe  b1=new Shengchangzhe(a);
                   Shengchangzhe  b2=new Shengchangzhe(a);
                   Xiaofeizhe     b3=new Xiaofeizhe(a);
       Xiaofeizhe     b4=newXiaofeizhe(a);
 
                   Thread  t1=new Thread(b1);
                Thread  t2=new Thread(b2);
             Thread t3=new Thread(b3);
                   Thread  t4=new Thread(b4);
 
       t1.start();
       t2.start();
             t3.start();
             t4.start();
                   System.out.println("HelloWorld!");
         }
}
/*
以上程序编译运行结果例如以下:
生产者Thread-0----1
Hello World!
消费者Thread-3----1
生产者Thread-1----2
消费者Thread-2----2
生产者Thread-0----3
消费者Thread-3----3
生产者Thread-1----4
消费者Thread-2----4
生产者Thread-0----5
消费者Thread-3----5
生产者Thread-1----6
消费者Thread-2----6
生产者Thread-0----7
消费者Thread-3----7
生产者Thread-1----8
消费者Thread-2----8
生产者Thread-0----9
消费者Thread-3----9
生产者Thread-1----10
消费者Thread-2----10
生产者Thread-0----11
消费者Thread-3----11
生产者Thread-1----12
消费者Thread-2----12
生产者Thread-0----13
消费者Thread-3----13
生产者Thread-1----14
消费者Thread-2----14
生产者Thread-0----15
消费者Thread-3----15
生产者Thread-1----16
消费者Thread-2----16
生产者Thread-0----17
消费者Thread-3----17
生产者Thread-1----18
消费者Thread-2----18
生产者Thread-0----19
消费者Thread-3----19
生产者Thread-1----20
消费者Thread-2----20
生产者Thread-0----21
消费者Thread-3----21
生产者Thread-1----22
消费者Thread-2----22
生产者Thread-0----23
消费者Thread-3----23
生产者Thread-1----24
消费者Thread-2----24
生产者Thread-0----25
消费者Thread-3----25
生产者Thread-1----26
消费者Thread-2----26
生产者Thread-0----27
消费者Thread-3----27
生产者Thread-1----28
消费者Thread-2----28
生产者Thread-0----29
消费者Thread-3----29
生产者Thread-1----30
消费者Thread-2----30
生产者Thread-0----31
*/

——————切割线————

 

//另外一个是jdk1.5版本号升级后的情况:
import java.util.concurrent.locks.*;
//这个导入的是后面须要用到的类
 
/*
随着jdk1.5版本号的升级,一些新的功能也被增加。更加的方便使用者
就拿多线程通信的生产者消费者样例来说
*/
 
class   Xctx6
{
         public  static  void  main(String[] args)
         {
                   Shipin  a=new Shipin();
 
                   Shengchangzhe  b1=new Shengchangzhe(a);                
                   Xiaofeizhe     b2=new Xiaofeizhe(a);     
 
                   Thread  t1=new Thread(b1);
                   Thread  t2=new Thread(b1);
                   Thread t3=new Thread(b2);
                   Thread  t4=new Thread(b2);
 
             t1.start();
             t2.start();
             t3.start();
             t4.start();
                   System.out.println("HelloWorld!");
         }
}
class   Shipin
{
         private  int sp=0;
         private  boolean  f=true;
         private  Lock   lock=new   ReentrantLock();//将锁作为一个对象了
 
   private  Condition  pro= lock.newCondition();
   private  Condition  con= lock.newCondition();
   /*
             Condition将Object监视器(锁)的方法(wait,notify。notifyAll)分解成不同的对象,
                   这是为了便于与Lock组合使用。
       Lock取代synchronized方法和语句的使用(同步函数和同步代码块)
                   Condition替代了Object监视器(锁)的方法的使用。
                   Condition实例是绑定在锁上的。一个Lock实例要获得Condition实例就要调用newCondition方法。

*/ public void shengchang() throws InterruptedException { lock.lock(); try { while(f==false) pro.await();//生产者线程陷入冻结 //这个句式会抛出一个InterruptedException异常 sp++; System.out.println("生产者"+Thread.currentThread().getName()+"----"+sp); f=false; con.signal();//只唤醒消费者线程 } finally { lock.unlock();//释放锁 } /* 这里是所以要使用try...finally句型是由于确保 一定要运行 lock.unlock();也是由于前面的pro.await();会向外抛出 一个异常,假设没有这个句型程序就会跳出去而没有 运行lock.unlock();这种话线程就没有释放锁 */ } public void xiaofei() throws InterruptedException { lock.lock(); try { while(f==true) con.await();//消费者线程陷入冻结 System.out.println("消费者"+Thread.currentThread().getName()+"----"+sp); f=true; pro.signal();//唤醒生产者线程 } finally { lock.unlock(); } } } class Shengchangzhe implements Runnable { private Shipin a ; Shengchangzhe(Shipin a) { this.a=a; } public void run() { while(true) { try{a.shengchang();} catch(Exception e){} } } } class Xiaofeizhe implements Runnable { private Shipin a ; Xiaofeizhe(Shipin a) { this.a=a; } public void run() { while(true) { try{a.xiaofei();} catch(Exception e){} } } }


/*

对前面的样例做了一个改进:

有生产者,检查者。消费者

先要由生产者生产食品,

然后由检查者检測食品。

最后由消费者消化食品。

*/

import java.util.concurrent.locks.*;
 
class  Xctx7
{
         public  static  void  main(String[] args)
         {
                   Shipin  a=new Shipin();
 
                   Shengchangzhe  b1=new Shengchangzhe(a);                
                   Xiaofeizhe     b2=new Xiaofeizhe(a);
                   Jiancezhe      b3=new Jiancezhe(a);
 
                   Thread  t1=new Thread(b1);
                   Thread  t2=new Thread(b1);
                   Thread t3=new Thread(b2);
                   Thread  t4=new Thread(b2);
                   Thread t5=new Thread(b3);
                   Thread  t6=new Thread(b3);
 
 
             t1.start();
             t2.start();
             t3.start();
             t4.start();
             t5.start();
             t6.start();
                   System.out.println("HelloWorld!");
         }
}
class   Shipin
{
         private  int sp=0;
         private  int  f=1;
         private  Lock lock=new ReentrantLock();//将锁作为一个对象了
 
   private  Condition  pro= lock.newCondition();
   private  Condition  con= lock.newCondition();
   private  Condition  jc = lock.newCondition();
 
         public    void shengchang() throws InterruptedException 
         {
                   lock.lock();
                   try
                   {
                    while(f!=1)
                             {
                             pro.await();//生产者线程陷入冻结
                             }
                    
        sp++;
              System.out.println("生产者"+Thread.currentThread().getName()+"----"+sp);
                  
                    f=2;
                   jc.signal();//唤醒检測者线程
                   }
                   finally
                   {
                        lock.unlock();//释放锁
                   }       
                  
         }
         public  void  xiaofei() throws   InterruptedException 
         {
                   lock.lock();
                   try
                   {
 
                     while(f!=3)
                            {
                       con.await();//消费者线程陷入冻结
                            }
                           
                System.out.println("消费者"+Thread.currentThread().getName()+"----------"+sp);
                      f=1;
                      pro.signal();//唤醒生产者线程
                   }
                   finally
                   {
                     lock.unlock();
                   }
         }
   public  void  jiance() throws  InterruptedException  //检測方法
         {
                   lock.lock();
                   try
                   {
 
                     while(f!=2)
                            {
                       jc.await();//检測者线程陷入冻结
                           
                            }
                System.out.println("检測者"+Thread.currentThread().getName()+"-------"+sp);
                      f=3;
                      con.signal();//唤醒消费者线程
                   }
                   finally
                   {
                     lock.unlock();
                   }
         }
 
}
class   Shengchangzhe  implements  Runnable
{
         privateShipin   a ;
         Shengchangzhe(Shipin   a)
         {
             this.a=a;
         }
   public   void   run()
         {
                   while(true)
                   {
                     try{a.shengchang();}
                     catch(Exception e){}
                   }
         }
}
 
class   Xiaofeizhe  implements   Runnable
{
   private   Shipin   a ;
         Xiaofeizhe(Shipin   a)
         {
             this.a=a;
         }
   public  void  run()
         {
                   while(true)
                   {
                     try{a.xiaofei();}
                     catch(Exception e){}
                   }
         }
}
class   Jiancezhe  implements Runnable
{
   private   Shipin   a ;
         Jiancezhe(Shipin   a)
         {
             this.a=a;
         }
   public   void   run()
         {
                   while(true)
                   {
                     try{a.jiance();}
                     catch(Exception e){}
                   }
         }
}
/*
以上的代码编译执行结果例如以下:
生产者Thread-0----1
Hello World!
检測者Thread-4-------1
消费者Thread-3----------1
生产者Thread-0----2
检測者Thread-5-------2
消费者Thread-3----------2
生产者Thread-1----3
检測者Thread-5-------3
消费者Thread-2----------3
生产者Thread-0----4
检測者Thread-4-------4
消费者Thread-3----------4
生产者Thread-1----5
检測者Thread-5-------5
消费者Thread-2----------5
生产者Thread-0----6
检測者Thread-4-------6
消费者Thread-3----------6
生产者Thread-1----7
检測者Thread-5-------7
消费者Thread-2----------7
生产者Thread-0----8
检測者Thread-4-------8
消费者Thread-3----------8
生产者Thread-1----9
检測者Thread-5-------9
消费者Thread-2----------9
生产者Thread-0----10
检測者Thread-4-------10
消费者Thread-3----------10
生产者Thread-1----11
检測者Thread-5-------11
消费者Thread-2----------11
生产者Thread-0----12
检測者Thread-4-------12
消费者Thread-3----------12
生产者Thread-1----13
检測者Thread-5-------13
消费者Thread-2----------13
生产者Thread-0----14
检測者Thread-4-------14
消费者Thread-3----------14
生产者Thread-1----15
检測者Thread-5-------15
消费者Thread-2----------15
生产者Thread-0----16
检測者Thread-4-------16
消费者Thread-3----------16
生产者Thread-1----17
检測者Thread-5-------17
消费者Thread-2----------17
生产者Thread-0----18
检測者Thread-4-------18
消费者Thread-3----------18
生产者Thread-1----19
检測者Thread-5-------19
消费者Thread-2----------19
生产者Thread-0----20
检測者Thread-4-------20
消费者Thread-3----------20
生产者Thread-1----21
检測者Thread-5-------21
消费者Thread-2----------21
生产者Thread-0----22
检測者Thread-4-------22
消费者Thread-3----------22
生产者Thread-1----23
检測者Thread-5-------23
消费者Thread-2----------23
生产者Thread-0----24
检測者Thread-4-------24
消费者Thread-3----------24
生产者Thread-1----25
检測者Thread-5-------25
消费者Thread-2----------25
生产者Thread-0----26
检測者Thread-4-------26
消费者Thread-3----------26
生产者Thread-1----27
检測者Thread-5-------27
消费者Thread-2----------27
生产者Thread-0----28
检測者Thread-4-------28
消费者Thread-3----------28
生产者Thread-1----29
检測者Thread-5-------29
消费者Thread-2----------29
生产者Thread-0----30
检測者Thread-4-------30
消费者Thread-3----------30
生产者Thread-1----31
检測者Thread-5-------31
消费者Thread-2----------31
生产者Thread-0----32
检測者Thread-4-------32
消费者Thread-3----------32
生产者Thread-1----33
检測者Thread-5-------33
消费者Thread-2----------33
生产者Thread-0----34
检測者Thread-4-------34
消费者Thread-3----------34
生产者Thread-1----35
检測者Thread-5-------35
消费者Thread-2----------35
生产者Thread-0----36
检測者Thread-4-------36
消费者Thread-3----------36
生产者Thread-1----37
检測者Thread-5-------37
消费者Thread-2----------37
生产者Thread-0----38
检測者Thread-4-------38
消费者Thread-3----------38
生产者Thread-1----39
检測者Thread-5-------39
消费者Thread-2----------39
生产者Thread-0----40
检測者Thread-4-------40
消费者Thread-3----------40
生产者Thread-1----41
检測者Thread-5-------41
消费者Thread-2----------41
生产者Thread-0----42
检測者Thread-4-------42
消费者Thread-3----------42
生产者Thread-1----43
检測者Thread-5-------43
消费者Thread-2----------43
生产者Thread-0----44
检測者Thread-4-------44
消费者Thread-3----------44
生产者Thread-1----45
检測者Thread-5-------45
消费者Thread-2----------45
生产者Thread-0----46
检測者Thread-4-------46
消费者Thread-3----------46
生产者Thread-1----47
检測者Thread-5-------47
消费者Thread-2----------47
生产者Thread-0----48
检測者Thread-4-------48
消费者Thread-3----------48
生产者Thread-1----49
检測者Thread-5-------49
消费者Thread-2----------49
生产者Thread-0----50
检測者Thread-4-------50
消费者Thread-3----------50
生产者Thread-1----51
检測者Thread-5-------51
消费者Thread-2----------51
生产者Thread-0----52
检測者Thread-4-------52
消费者Thread-3----------52
生产者Thread-1----53
检測者Thread-5-------53
消费者Thread-2----------53
生产者Thread-0----54
检測者Thread-4-------54
消费者Thread-3----------54
生产者Thread-1----55
检測者Thread-5-------55
消费者Thread-2----------55
生产者Thread-0----56
检測者Thread-4-------56
消费者Thread-3----------56
生产者Thread-1----57
检測者Thread-5-------57
消费者Thread-2----------57
生产者Thread-0----58
检測者Thread-4-------58
消费者Thread-3----------58
生产者Thread-1----59
检測者Thread-5-------59
消费者Thread-2----------59
生产者Thread-0----60
检測者Thread-4-------60
消费者Thread-3----------60
生产者Thread-1----61
检測者Thread-5-------61
消费者Thread-2----------61
生产者Thread-0----62
检測者Thread-4-------62
消费者Thread-3----------62
生产者Thread-1----63
检測者Thread-5-------63
消费者Thread-2----------63
*/

posted @ 2017-04-20 13:17  llguanli  阅读(135)  评论(0编辑  收藏  举报