单单在概念上理解清楚了还不够,需要在实际的例子中进行测试才能更好的理解。对Object.wait(),Object.notify()的应用最经典的例子,应该是三线程打印ABC的问题了吧,这是一道比较经典的面试题,题目要求如下:
建立三个线程,A线程打印10次A,B线程打印10次B,C线程打印10次C,要求线程同时运行,交替打印10次ABC。这个问题用Object的wait(),notify()就可以很方便的解决。代码如下:
1 public class MyThreadPrinter implements Runnable{ 2 3 private String name; 4 private Object prev; 5 private Object self; 6 7 private MyThreadPrinter(String name,Object prev,Object self){ 8 this.name = name; 9 this.prev = prev; 10 this.self = self; 11 } 12 13 public void run(){ 14 int count = 10; 15 while(count>0){ 16 synchronized(prev){ 17 synchronized (self) { 18 System.out.println("正在打印的是:"+name+"---"+count); 19 count--; 20 self.notify(); 21 } 22 if(count>0){ 23 try { 24 prev.wait(); 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 } 29 30 } 31 } 32 } 33 34 public static void main(String[] args){ 35 Object a = new Object(); 36 Object b = new Object(); 37 Object c = new Object(); 38 MyThreadPrinter pa = new MyThreadPrinter("A", c, a); 39 MyThreadPrinter pb = new MyThreadPrinter("B", a, b); 40 MyThreadPrinter pc = new MyThreadPrinter("C", b, c); 41 42 new Thread(pa).start(); 43 new Thread(pb).start(); 44 new Thread(pc).start(); 45 46 47 } 48 49 }
public void run(){ int count = 10; while(count>0){ synchronized(prev){ synchronized (self) { System.out.println("正在打印的是:"+name+"---"+count); count--; try{ Thread.sleep(1); } catch (InterruptedException e){ e.printStackTrace(); } self.notify(); } if(count>0){ try { prev.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
运行后的打印结果就变成了ACBACB了。为了避免这种与JVM调度有关的不确定性。需要让A,B,C三个线程以确定的顺序启动,最终代码如下:
1 public class MyThreadPrinter implements Runnable{ 2 3 private String name; 4 private Object prev; 5 private Object self; 6 7 private MyThreadPrinter(String name,Object prev,Object self){ 8 this.name = name; 9 this.prev = prev; 10 this.self = self; 11 } 12 13 public void run(){ 14 int count = 10; 15 while(count>0){ 16 synchronized(prev){ 17 synchronized (self) { 18 System.out.println("正在打印的是:"+name+"---"+count); 19 count--; 20 try{ 21 Thread.sleep(1); 22 } 23 catch (InterruptedException e){ 24 e.printStackTrace(); 25 } 26 self.notify(); 27 } 28 if(count>0){//防止最后的对象b在wait()之后没有线程来唤醒了 29 try { 30 prev.wait(); 31 } catch (InterruptedException e) { 32 e.printStackTrace(); 33 } 34 } 35 36 } 37 } 38 } 39 40 public static void main(String[] args){ 41 Object a = new Object(); 42 Object b = new Object(); 43 Object c = new Object(); 44 MyThreadPrinter pa = new MyThreadPrinter("A", c, a); 45 MyThreadPrinter pb = new MyThreadPrinter("B", a, b); 46 MyThreadPrinter pc = new MyThreadPrinter("C", b, c); 47 48 try{ 49 new Thread(pa).start(); 50 Thread.sleep(1); 51 new Thread(pb).start(); 52 Thread.sleep(1); 53 new Thread(pc).start(); 54 Thread.sleep(1); 55 }catch(InterruptedException e){ 56 e.printStackTrace(); 57 } 58 } 59 60 }
wait(), notify(),sleep详解,布布扣,bubuko.com
原文:http://www.cnblogs.com/xingele0917/p/3630935.html