java wait()/notify() 实现生产者消费者模式

Java中的多线程会涉及到线程间通信,常见的线程通信方式,例如共享变量、管道流等,这里我们要实现生产者消费者模式,也需要涉及到线程通信,不过这里我们用到了java中的wait()、notify()方法:

wait():进入临界区的线程在运行到一部分后,发现进行后面的任务所需的资源还没有准备充分,所以调用wait()方法,让线程阻塞,等待资源,同时释放临界区的锁,此时线程的状态也从RUNNABLE状态变为WAITING状态;

notify():准备资源的线程在准备好资源后,调用notify()方法通知需要使用资源的线程,同时释放临界区的锁,将临界区的锁交给使用资源的线程。

wait()、notify()这两个方法,都必须要在临界区中调用,即是在synchronized同步块中调用,不然会抛出IllegalMonitorStateException的异常。

实现源码:

生产者线程类:

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package threads;  
  2.   
  3. import java.util.List;  
  4. import java.util.UUID;  
  5.   
  6. public class Producer extends Thread{  
  7.   
  8.     private List<String> storage;//生产者仓库  
  9.     public Producer(List<String> storage) {  
  10.         this.storage = storage;  
  11.     }  
  12.     public void run(){  
  13.         //生产者每隔1s生产1~100消息  
  14.         long oldTime = System.currentTimeMillis();  
  15.         while(true){  
  16.             synchronized(storage){  
  17.                 if (System.currentTimeMillis() - oldTime >= 1000) {  
  18.                     oldTime = System.currentTimeMillis();  
  19.                     int size = (int)(Math.random()*100) + 1;  
  20.                     for (int i = 0; i < size; i++) {  
  21.                         String msg = UUID.randomUUID().toString();  
  22.                         storage.add(msg);  
  23.                     }  
  24.                     System.out.println("线程"+this.getName()+"生产消息"+size+"条");  
  25.                     storage.notify();  
  26.                 }  
  27.             }  
  28.         }  
  29.     }  
  30. }  


消费者线程类:

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package threads;  
  2.   
  3. import java.util.List;  
  4.   
  5. public class Consumer extends Thread{  
  6.   
  7.     private List<String> storage;//仓库  
  8.     public Consumer(List<String> storage) {  
  9.         this.storage = storage;  
  10.     }  
  11.     public void run(){  
  12.         while(true){  
  13.             synchronized(storage){  
  14.                 //消费者去仓库拿消息的时候,如果发现仓库数据为空,则等待  
  15.                 if (storage.isEmpty()) {  
  16.                     try {  
  17.                         storage.wait();  
  18.                     } catch (InterruptedException e) {  
  19.                         e.printStackTrace();  
  20.                     }  
  21.                 }  
  22.                 int size = storage.size();  
  23.                 for (int i = size - 1; i >= 0; i--) {  
  24.                     storage.remove(i);  
  25.                 }  
  26.                 System.out.println("线程"+this.getName()+"成功消费"+size+"条消息");  
  27.             }  
  28.         }  
  29.     }  
  30. }  


仓库类:

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package threads;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. public class Storage {  
  7.   
  8.     private List<String> storage;//生产者和消费者共享的仓库  
  9.     public Storage() {  
  10.         storage = new ArrayList<String>();  
  11.     }  
  12.     public List<String> getStorage() {  
  13.         return storage;  
  14.     }  
  15.     public void setStorage(List<String> storage) {  
  16.         this.storage = storage;  
  17.     }  
  18.       
  19. }  


main方法类:

 

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. package threads;  
  2.   
  3. public class App {  
  4.   
  5.     public static void main(String[] args) {  
  6.         Storage storage = new Storage();  
  7.         Producer producer = new Producer(storage.getStorage());  
  8.         Consumer consumer = new Consumer(storage.getStorage());  
  9.         producer.start();  
  10.         consumer.start();  
  11.     }  
  12. }  


生产消费效果:

 

posted @ 2016-12-08 17:16  天涯海角路  阅读(144)  评论(0)    收藏  举报