Java thread communication learning (multi-threaded (synchronized))

Analysis threads a classic case of producers and consumers

 1 /**
 2 共享数据
 3 */
 4 class Resource
 5 {
 6     private String name;
 7     private int count=1;
 8     private boolean flag=false;
 9     
10     public synchronized void set(String name)
11     {    
12         if(flag)
13             try{this.wait();}catch(InterruptedException e){}
14         this.name=name+count;
15         count++;
16         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
17         flag = true;
18         notify();
19     }
20     
21     public synchronized void out() 
22     {
23         if(!flag)
24             try{this.wait();}catch(InterruptedException e){}
25         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
 26 is          In Flag = to false ;
 27          Notify ();
 28      }
 29  }
 30  
31 is  // custom thread tasks (producer thread) 
32  class Producer the implements the Runnable
 33 is  {
 34 is      Private the Resource R & lt;
 35      
36      Producer (the Resource R & lt)
 37 [      {
 38 is          the this .r = R & lt;
 39      }
 40      public  void RUN ()
 41 is      {
 42 is          the while ( to true )
43 is          {
 44 is              r.set ( "product" );
 45          }
 46      }
 47  }
 48  // defined task thread (thread consumer) 
49  class Consumer the implements the Runnable
 50  {
 51 is      Private the Resource R & lt;
 52 is      
53 is      Consumer (the Resource R & lt)
 54 is      {
 55          the this .r = R & lt;
 56 is      }
 57 is      
58      public  void RUN ()
 59      {
 60          the while ( to true )
61 is          {
 62 is              r.out ();
 63 is          }
 64      }
 65  }
 66  
67  class ProducerConsumerDemo
 68  {
 69      public  static  void main (String [] args)
 70      {
 71 is          // instantiate the shared resources 
72          the Resource = R & lt new new the Resource ();
 73          // instantiate threaded task, specify the shared resources 
74          Producer P = new new Producer (R & lt);
 75          Consumer C = new new Consumer (R & lt);
 76          //Examples of the thread, the task specified thread 
77          the Thread = T0 new new the Thread (P);
 78          the Thread = T1 new new the Thread (P);
 79          the Thread T2 = new new the Thread (C);
 80          the Thread T3 = new new the Thread (C);
 81          // open threads, run method of a thread of execution task 
82          t0.start ();
 83          t1.start ();
 84          t2.start ();
 85          t3.start ();
 86      }
 87 }

operation result:

 

 

Result analysis:

 

So how then judge flag it? while

code show as below:

 1 class Resource
 2 {
 3     private String name;
 4     private int count=1;
 5     private boolean flag=false;
 6     
 7     public synchronized void set(String name) // 有两个线程t0 t1
 8     {    
 9         while(flag)
10             try{this.wait();}catch(InterruptedException e){}
11         this.name=name+count;
12         count++;
13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
14         flag = true;
15         notify();
16     }
17     
18     public synchronized void out() // 有两个线程t2 t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}
22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
23         flag = false;
24         notify();
25     }
26 }

结果出现死锁:

 

结果分析:

通过分析,那能不能每次唤醒只唤醒对方线程(如生产者线程只唤醒消费者线程,消费者线程只唤醒生产者线程),查看Object对象方法中没有,但是有一个notifyAll()方法,实在不行就把所有阻塞线程(相同同步锁的线程)都唤醒。

 1 class Resource
 2 {
 3     private String name;
 4     private int count=1;
 5     private boolean flag=false;
 6     
 7     public synchronized void set(String name) // 有两个线程t0 t1
 8     {    
 9         while(flag)
10             try{this.wait();}catch(InterruptedException e){}
11         this.name=name+count;
12         count++;
13         System.out.println(Thread.currentThread().getName() + "...生产者..." + this.name);
14         flag = true;
15         notifyAll();
16     }
17     
18     public synchronized void out() // 有两个线程t2 t3
19     {
20         while(!flag)
21             try{this.wait();}catch(InterruptedException e){}
22         System.out.println(Thread.currentThread().getName() + "==消费者==" + this.name);
23         flag = false;
24         notifyAll();
25     }
26 }

结果:

 

这样就可以了。

总结:

if判断只能判断一次,如果执行等待方法,下次唤醒的线程获取执行权后(唤醒后的线程会从上次等待位置,向下执行)就不能再判断

while判断解决唤醒的线程获取执行权后无法判断

notify:只能唤醒任意一个线程,有可能会唤醒本方线程,while+notify会导致死锁

notifyAll:解决了死锁问题

 

Guess you like

Origin www.cnblogs.com/WarBlog/p/12082961.html