哪些条件的实现不需要当前线程来保持锁定?

时间:2016-04-06 11:04:04

标签: multithreading parallel-processing locking java.util.concurrent concurrent-programming

最近,我阅读了The Art of Multiprocessor Programming第8章中关于使用signalAll() Condition对象的{{1>}的“监视器和阻止同步”的一些示例,没有获得与Condition相关联的锁。

令人惊讶的是,我没有找到book’s errata中这些示例的任何修复。此外,他们建议对FifoReadWriteLock的图8.12的示例进行更正,但是他们继续使用signalAll()而没有锁定。这扰乱了我,我试图找到关于这些示例的其他注意事项,以了解这些Java示例以这种方式编写的原因。

例如,问题“answer”的How does a read-write mutex/lock work?显示了FifoReadWriteLock的实现的相同示例,它将writeUnlock()实现为:

void writeUnlock() {
    writer = false;
    condition.signalAll();
}

关于没有锁定获取,您可以阅读两个不同的原因:

  1. 仅将其用作伪代码
  2. 条件变量的某些实现并不要求锁定信号。
  3. 很难接受第一个参数,因为book使用Java中的示例并明确说:

      

    本书使用Java编程语言。

    关于第二点,我知道java.util.concurrent.locks.ConditionCondition的Java API表示signal()方法:

      

    实现可能(并且通常会)要求当调用此方法时,当前线程保持与此Condition关联的锁。

    如果" 实施可能 "只是,这意味着它不是强制性的。然而,据我所知,我发现任何不符合此要求的实施方案。所以我想知道哪些Java {{1}}实现不需要当前线程来保存锁?

1 个答案:

答案 0 :(得分:1)

我不知道JDK中的任何Condition实现允许在不拥有监视器的情况下等待或发送信号。

实际上,所有java.util.concurrent类都依赖于AbstractQueuedSynchronizer,它与内置监控方法wait() / notify() / notifyAll()建立了相同的合同。它提供的条件变量,即它需要拥有内部锁,以便允许调用await() / signal() / signalAll()

如果您尝试使用建议的FifoReadWriteLock的简单示例,您会发现它使用IllegalMonitorStateExceptions方法提供了大量writeUnlock()礼貌。如果您从其他方法应用lock-try-finally方法,这些异常将消失。

虽然确实拥有显示器并不是绝对需要等待或发出信号,但通常它是更好的方法,因为它可以避免您进行有条不紊的读取操作,它不应该像交接一样昂贵相同监视器的内部等待集之间仍然可以相当有效地完成,因为大多数情况下,您需要它来进行信令和调度,而不仅仅是信令。