gpt4 book ai didi

java - 我可以在Java中用两个对象作为锁来实现阻塞队列吗?

转载 作者:行者123 更新时间:2023-12-01 10:29:29 24 4
gpt4 key购买 nike

我试图通过实现一个阻塞队列类来理解Java的synchronized关键字、wait()和notify()。 this 描述了一种阻塞队列实现。文章。但是我想知道是否可以使用两个对象作为锁来实现阻塞队列?下面的代码正确吗?

public class BlockingQueue {
private List<Object> queue = new LinkedList<Object>();
private int limit;
private Object slots = new Object();
private Object objs = new Object();
public BlockingQueue(int limit) {
this.limit = limit;
}
private synchronized void enqueue(Object o)
throws InterruptedException {
if (queue.size() == limit)
slots.wait();
objs.notify();
queue.add(o);
}
private synchronized Object dequeue()
throws InterruptedException {
if (queue.size() == 0)
objs.wait();
slots.notify();
return queue.remove(0);
}
}

最佳答案

首先,您无法等待或通知未同步的对象。在这里您将使用 this.wait() 和 this.notifyAll。

其次,你不应该只 wait() 一次而不重新检查你的条件。无论您在“if”中放入什么内容,都应该在 while 循环中;这是因为您可能会在条件没有改变的情况下错误地收到通知,特别是因为您在实例上使用监视器,外部任何人都可以在该实例上进行同步和通知。您应该使用同步(私有(private)锁对象){}。

这引出了您的问题,您可以同步 2 个以上对象吗...是的,通过嵌套同步块(synchronized block),但这会导致挂起代码,因为 wait() 调用仅释放您等待的一个监视器,而不是释放外部监视器。因此这是毫无意义的。

如果您试图避免通知在队列中等待的读取者和写入者,这是一个值得尊敬的想法,但您不能使用同步来做到这一点。引用的示例是使用单个监视器执行此操作,这也是它必须使用 notifyAll() 而不是 notify() 的原因,因为您要确保唤醒正确的等待线程。通常,您必须在两个不同的条件(非空和非满)下使用 ReentrantLock。

关于java - 我可以在Java中用两个对象作为锁来实现阻塞队列吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35167262/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com