线程 - 生产者消费者模式

生产者消费者模型

生产者/消费者模式其实是一种很经典的线程同步模型,很多时候,并不是光保证多个线程对某共享资源操作的互斥性就够了,往往多个线程之间都是有协作的。
假设有这样一种情况,有一个桌子,桌子上面有一个盘子,盘子里只能放一颗鸡蛋,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();
        }
    }
}

 

posted @ 2017-11-16 14:24  NewQ  阅读(181)  评论(0)    收藏  举报