gpt4 book ai didi

java - 急切地条件#signal 是最佳实践吗?

转载 作者:行者123 更新时间:2023-11-30 10:59:46 24 4
gpt4 key购买 nike

Condition JavaDoc具有以下代码示例:

class BoundedBuffer {
final Lock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final Condition notEmpty = lock.newCondition();

final Object[] items = new Object[100];
int putptr, takeptr, count;

public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length)
notFull.await();
items[putptr] = x;
if (++putptr == items.length) putptr = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}

public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0)
notEmpty.await();
Object x = items[takeptr];
if (++takeptr == items.length) takeptr = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}

如果我实现了 BoundedBuffer#take,我只会在 count == (items.length - 2) 时调用 notFull.signal() ) 除非必要,否则避免向其他线程发送信号。我还注意到 ArrayBlockingQueue#removeAt 急切地调用 notFull.signal();

问题:我的支票会引入错误吗? Java 并发编程的最佳实践是在条件为真时急切发出信号吗?我认为它会降低死锁的风险。它对性能有影响吗?

最佳答案

是的。您的检查引入了错误。用病理学的例子很容易证明。

假设 count = items.length:

Thread1: put(o1); // count == items.length. Waiting on notFull.
Thread2: put(o2); // Waiting on notFull.
Thread3: put(o3); // Waiting on notFull.
Thread4: take(); // count -> items.length - 1
// There's space in the buffer, but we never signalled notFull.
// Thread1, Thread2, Thread3 will still be waiting to put.
take(); // count -> items.length - 2, signal notFull!
// But what happens if Thread4 manages to keep the lock?
take(); // count -> items.length - 3
...
take(); // count -> 0
Thread1: // Wakes up from Thread4's signal.
put(o1); // count -> 1
Thread2: put(o2); // Never signalled, still waiting on notFull.
Thread3: put(o3); // Never signalled, still waiting on notFull.

这可以通过使用 signalAll 来缓解,但您仍然会遇到几个问题:

  1. 由于即使只有一个空间被打开,您也会唤醒每个线程,因此会有更多的锁争用。
  2. 当您的缓冲区中正好有一个空位时,您仍然会有线程等待put。根据实现/文档,我想这可能没问题,但在大多数情况下它仍然会令人惊讶。

关于java - 急切地条件#signal 是最佳实践吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31804895/

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