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

Mig*_*boa 8 parallel-processing multithreading locking java.util.concurrent concurrent-programming

最近,我从" 多处理器编程的艺术 "第8章中读到了一些关于" 监视器和阻塞同步 "的例子,这些例子使用了signalAll()一个Condition对象,而没有获得与之相关的锁Condition.

令人惊讶的是,我没有在本书的勘误表中找到任何修复这些例子的方法.此外,他们建议对a的图8.12的例子进行修正FifoReadWriteLock,但他们继续使用signalAll()没有锁定的情况.这扰乱了我,我试图找到关于这些示例的其他注意事项,以了解这些Java示例以这种方式编写的原因.

例如,问题的答案 " 读写互斥锁如何工作?"显示了a的实现的相同示例FifoReadWriteLock,它实现了writeUnlock():

void writeUnlock() {
    writer = false;
    condition.signalAll();
}
Run Code Online (Sandbox Code Playgroud)

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

  1. 仅将其用作伪代码
  2. 条件变量的某些实现不要求锁定信号.

由于本书使用了Java中的示例并明确说明了以下内容,因此很难接受第一个参数:

本书使用Java编程语言.

关于第二点,我知道方法的java.util.concurrent.locks.Condition状态中的Java API signal():

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

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

Dim*_*rov 1

我不知道ConditionJDK 中是否有任何实现允许在不同时拥有监视器的情况下等待或发信号。

实际上,所有类都java.util.concurrent依赖它为它提供的条件变量AbstractQueuedSynchronizer建立与内置监视器方法相同的契约wait(),即它需要拥有内部锁才能允许调用//notify()notifyAll()await()signal()signalAll()实际上,

如果您尝试使用提议的简单示例,您会发现它对其方法FifoReadWriteLock表现出了极大的礼貌。如果您应用其他方法中的 lock-try-finally 方法,这些异常就会消失。IllegalMonitorStateExceptionswriteUnlock()

虽然确实拥有监视器并不是绝对需要等待或发出信号,但通常这是更好的方法,因为它可以使您免于频繁的条件读取,但它不应该太昂贵,因为同一监视器的内部等待集之间的切换仍然可以相当有效地完成,因为大多数情况下您需要它用于信令和调度,而不仅仅是信令。