生产者消费者模型
生产者/消费者模式其实是一种很经典的线程同步模型,很多时候,并不是光保证多个线程对某共享资源操作的互斥性就够了,往往多个线程之间都是有协作的。
假设有这样一种情况,有一个桌子,桌子上面有一个盘子,盘子里只能放一颗鸡蛋,A专门往盘子里放鸡蛋,如果盘子里有鸡蛋,则一直等到盘子里没鸡蛋,B专门从盘子里拿鸡蛋,如果盘子里没鸡蛋,则等待直到盘子里有鸡蛋。其实盘子就是一个互斥区,每次往盘子放鸡蛋应该都是互斥的,A的等待其实就是主动放弃锁,B等待时还要提醒A放鸡蛋。
基于Condition+ReentrantLock实现
import java.util.LinkedList; import java.util.List; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Created by j_zhan on 2016/7/13. */ public class Queue<T> { private final T[] items; private final Lock lock = new ReentrantLock(); private Condition notFull = lock.newCondition(); private Condition notEmpty = lock.newCondition(); private int head, tail, count; public Queue(int maxSize) { items = (T[]) new Object[maxSize]; } public Queue() { this(10); } public void put(T t) throws InterruptedException { lock.lock(); try { while (count == items.length) { //数组满时,线程进入等待队列挂起。线程被唤醒时,从这里返回。 notFull.await(); } items[tail] = t; if (++tail == items.length) { tail = 0; } ++count; notEmpty.signal(); } finally { lock.unlock(); } } public T take() throws InterruptedException { lock.lock(); try { while (count == 0) { notEmpty.await(); } T o = items[head]; items[head] = null;//GC if (++head == items.length) { head = 0; } --count; notFull.signal(); return o; } finally { lock.unlock(); } } }