在并发编程中的一个经典问题是生产者与消费者问题:咱们有一个数据缓冲区,一个或多个数据的生产者在缓冲区存储数据,而一个或多个数据的消费者,把数据从缓冲区取出。java
因为缓冲区是一个共享的数据结构,咱们必须采用同步机制,好比 synchronized 关键字来控制对它的访问。可是咱们有更多的限制因素,若是缓冲区是满的,生产者不能存储数据,若是缓冲区是空的,消费者不能取出数据。编程
对于这些类型的状况,Java在Object对象中提供wait(),notify(),和notifyAll() 方法的实现。缓存
wait() 方法:数据结构
一、只能在同步代码块中调用并发
二、当一个线程调用 wait() 方法,jvm将这个线程置入休眠,而且释放控制这个同步代码快的对象,同时容许其余线程执行这个对象控制的其余同步代码块jvm
三、为了唤醒这个线程,必须在这个对象控制的某个同步代码快调用 notify() 方法或者 notifyAll() 方法ide
import java.util.Date; import java.util.concurrent.LinkedBlockingQueue; /** * 中间缓存 */ public class EventStorage { private int maxSize; private LinkedBlockingQueue<Date> storage; public EventStorage(int maxSize){ this.maxSize = maxSize; storage = new LinkedBlockingQueue<Date>(); } // 存放操做 public synchronized void set(){ // 在while循环中,你必须保持检查条件和调用wait()方法。你不能继续执行,直到这个条件为true。 while(storage.size() == maxSize){ //循环判断 为 真,才进行 线程 挂起操做. try { wait(); // 挂起 该线程,等待 剩余空间出现 } catch (InterruptedException e) { e.printStackTrace(); } } storage.offer(new Date()); System.out.println("存操做- storage size:" + storage.size()); notifyAll(); // 唤醒 全部 由于 wait() 操做而休眠的 线程. } // 取出操做 public synchronized void get(){ while(storage.size() == 0){ //循环判断 为 真,才进行 线程 挂起操做. try { wait(); // 挂起 该线程,等待 剩余空间出现 } catch (InterruptedException e) { e.printStackTrace(); } } storage.poll(); System.out.println("取出操做- storage size:" + storage.size()); notifyAll(); // 唤醒 全部 由于 wait() 操做而休眠的 线程. } }
import java.util.concurrent.TimeUnit; /** * 生产者 */ public class EventProducer implements Runnable{ private EventStorage eventStorage; public EventProducer(EventStorage eventStorage){ this.eventStorage = eventStorage; } @Override public void run() { while(true){ eventStorage.set(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }
/** * 消费者 */ public class EventCustomer implements Runnable{ private EventStorage eventStorage; public EventCustomer(EventStorage eventStorage){ this.eventStorage = eventStorage; } public void run() { while(true){ eventStorage.get(); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } }
public class EventTest { public static void main(String[] args) { EventStorage eventStorage = new EventStorage(3); EventProducer producer = new EventProducer(eventStorage); EventCustomer customer = new EventCustomer(eventStorage); Thread threadProducer = new Thread(producer); Thread threadCostomer = new Thread(customer); threadProducer.start(); threadCostomer.start(); } }