使用 Java 对象监视器实现阻塞有界队列 [关闭]

问题描述 投票:0回答:0

我正在通过在 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();
        }
    }
}

谁能解释为什么会出现这种死锁,以及我如何构建代码以使其在功能上与第一个代码相同?

java concurrency locking deadlock producer-consumer
© www.soinside.com 2019 - 2024. All rights reserved.