生产者模型和消费者模型

2019-11-10  本文已影响0人  真胖大海
image.png

一.单锁双条件的实现

public class MyBlockingQueue<T> {

    private int mCapacity;
    private LinkedList<T> mTable;

    private ReentrantLock lock = new ReentrantLock();
    private Condition mNotFull = lock.newCondition();
    private Condition mNotEmpty = lock.newCondition();


    public MyBlockingQueue(int mCapacity) {
        this.mCapacity = mCapacity;
        mTable = new LinkedList<>();
    }

    public boolean put(T t) {
        try {
            lock.lock();
            while(mTable.size()==mCapacity){
                mNotFull.await();
            }
            mTable.add(t);
            mNotEmpty.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        return true;
    }

    public T get() {
        T first=null;
        try {
            lock.lock();
            while(mTable.size()==0){
                mNotEmpty.await();
            }
            first=mTable.removeLast();
            mNotFull.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

        return first;
    }
}

二.双锁双条件的实现

public class MyBlockingQueue<T> {

    private int mCapacity;
    private LinkedList<T> mTable;

    private ReentrantLock mPutLock = new ReentrantLock();
    private ReentrantLock mGetLock = new ReentrantLock();
    private Condition mNotFull = mPutLock.newCondition();
    private Condition mNotEmpty = mGetLock.newCondition();
    private AtomicInteger count=new AtomicInteger(0);

    public MyBlockingQueue(int mCapacity) {
        this.mCapacity = mCapacity;
        mTable = new LinkedList<>();
    }

    public boolean put(T t) {
        mPutLock.lock();
        int c=-1;
        try {
            while (mTable.size() == mCapacity) {//这里使用whie是为了避免线程在条件不满足是被意外唤醒
                mNotFull.await();
            }

            mTable.addLast(t);
            c=count.getAndIncrement();
        } catch (InterruptedException e) {
            return false;
        } finally {
            mPutLock.unlock();
        }
        if (c == 0) {//只有原来数量为0的情况才唤醒在mNotEmpty上等待的线程
            mGetLock.lock();
            mNotEmpty.signal();
            mGetLock.unlock();
        }
        return true;
    }

    public T get() {
        T first=null;
        mGetLock.lock();
        int c=-1;
        try {
            while (mTable.size() == 0) {
                mNotEmpty.await();
            }
             first = mTable.removeFirst();
             c=count.getAndDecrement();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            mGetLock.unlock();
        }
        if (c== mCapacity) {//只有原来数量满了的情况才唤醒在mNotFull上等待的线程
            mPutLock.lock();
            mNotFull.signal();
            mPutLock.unlock();
        }
        return first;
    }
}

三. 两种实现的比较

因为单锁双条件只有一个锁,所以读的时候不能写,写的时候不能读
但是双锁双条件有两个锁,所以读的时候能写,写的时候能读。

上一篇 下一篇

猜你喜欢

热点阅读