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:解决了死锁问题