我正在通过在 Java 中实现我自己的有界阻塞队列的实践来学习更多关于 Java 中的并发和锁。我有以下使用
ReentrantLock
的实现,它似乎按预期工作
class BoundedBlockingQueue {
Queue<Integer> q;
int maxSize;
ReentrantLock lock;
Condition QUEUE_FULL;
Condition QUEUE_EMPTY;
public BoundedBlockingQueue(int capacity) {
q = new LinkedList<>();
maxSize = capacity;
lock = new ReentrantLock();
QUEUE_FULL = lock.newCondition();
QUEUE_EMPTY = lock.newCondition();
}
public void enqueue(int element) throws InterruptedException {
lock.lock();
try {
while (q.size() == maxSize) {
QUEUE_FULL.await();
}
q.offer(element);
QUEUE_EMPTY.signalAll();
} finally {
lock.unlock();
}
}
public int dequeue() throws InterruptedException {
lock.lock();
try {
while (q.size() == 0) {
QUEUE_EMPTY.await();
}
QUEUE_FULL.signalAll();
return q.poll();
} finally {
lock.unlock();
}
}
public int size() {
lock.lock();
try {
return q.size();
} finally {
lock.unlock();
}
}
}
我试图在不使用锁和条件变量的情况下编写等效代码。相反,我试图只使用对象监视器。我有以下尝试似乎陷入僵局
class BoundedBlockingQueue {
Queue<Integer> q;
int maxSize;
Object QUEUE_FULL;
Object QUEUE_EMPTY;
public BoundedBlockingQueue(int capacity) {
q = new LinkedList<>();
maxSize = capacity;
QUEUE_FULL = new Object();
QUEUE_EMPTY = new Object();
}
public void enqueue(int element) throws InterruptedException {
synchronized(q) {
synchronized(QUEUE_FULL) {
while (q.size() == maxSize) {
QUEUE_FULL.wait();
}
}
q.offer(element);
}
synchronized(QUEUE_EMPTY) {
QUEUE_EMPTY.notifyAll();
}
}
public int dequeue() throws InterruptedException {
int ret;
synchronized(q) {
synchronized(QUEUE_EMPTY) {
while (q.size() == 0) {
QUEUE_EMPTY.wait();
}
}
ret = q.poll();
}
synchronized(QUEUE_FULL) {
QUEUE_FULL.notifyAll();
}
return ret;
}
public int size() {
synchronized(q) {
return q.size();
}
}
}
谁能解释为什么会出现这种死锁,以及我如何构建代码以使其在功能上与第一个代码相同?