一.单锁双条件的实现
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;
}
}
三. 两种实现的比较
因为单锁双条件只有一个锁,所以读的时候不能写,写的时候不能读
但是双锁双条件有两个锁,所以读的时候能写,写的时候能读。
网友评论