标签:
1 // An incorrect implementation of a producer and consumer. 2 class Q { 3 int n; 4 synchronized int get() { 5 System.out.println("Got: " + n); 6 return n; 7 } 8 synchronized void put(int n) { 9 this.n = n; 10 System.out.println("Put: " + n); 11 } 12 } 13 class Producer implements Runnable { 14 Q q; 15 Producer(Q q) { 16 this.q = q; 17 new Thread(this, "Producer").start(); 18 } 19 public void run() { 20 int i = 0; 21 while(true) { 22 q.put(i++); 23 } 24 } 25 } 26 class Consumer implements Runnable { 27 Q q; 28 Consumer(Q q) { 29 this.q = q; 30 new Thread(this, "Consumer").start(); 31 } 32 public void run() { 33 while(true) { 34 q.get(); 35 } 36 } 37 } 38 class PC { 39 public static void main(String args[]) { 40 Q q = new Q(); 41 new Producer(q); 42 new Consumer(q); 43 System.out.println("Press Control-C to stop."); 44 } 45 }
尽管Q类中的put( )和get( )方法是同步的,没有东西阻止生产者超越消费者,也没有东西阻止消费者消费同样的序列两次。这样,你就得到下面的错误输出(输出将随处理器速度和装载的任务而改变):
Put: 11 // A correct implementation of a producer and consumer. 2 class Q { 3 int n; 4 boolean valueSet = false; 5 synchronized int get() { 6 if(!valueSet) 7 try { 8 wait(); 9 } catch(InterruptedException e) { 10 System.out.println("InterruptedException caught"); 11 } 12 System.out.println("Got: " + n); 13 valueSet = false; 14 notify(); 15 return n; 16 } 17 synchronized void put(int n) { 18 if(valueSet) 19 try { 20 wait(); 21 } catch(InterruptedException e) { 22 System.out.println("InterruptedException caught"); 23 } 24 this.n = n; 25 valueSet = true; 26 System.out.println("Put: " + n); 27 notify(); 28 } 29 } 30 class Producer implements Runnable { 31 Q q; 32 Producer(Q q) { 33 this.q = q; 34 new Thread(this, "Producer").start(); 35 } 36 public void run() { 37 int i = 0; 38 while(true) { 39 q.put(i++); 40 } 41 } 42 } 43 class Consumer implements Runnable { 44 Q q; 45 Consumer(Q q) { 46 this.q = q; 47 new Thread(this, "Consumer").start(); 48 } 49 public void run() { 50 while(true) { 51 q.get(); 52 } 53 } 54 } 55 class PCFixed { 56 public static void main(String args[]) { 57 Q q = new Q(); 58 new Producer(q); 59 new Consumer(q); 60 System.out.println("Press Control-C to stop."); 61 } 62 }
内部get( ), wait( )被调用。这使执行挂起直到Producer 告知数据已经预备好。这时,内部get( ) 被恢复执行。获取数据后,get( )调用notify( )。这告诉Producer可以向序列中输入更多数据。在put( )内,wait( )挂起执行直到Consumer取走了序列中的项目。当执行再继续,下一个数据项目被放入序列,notify( )被调用,这通知Consumer它应该移走该数据。
标签:
原文地址:http://www.cnblogs.com/Coda/p/4505020.html