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



最近我读到《多处理器编程的艺术》第8章中的一些例子,关于">监视器和阻塞同步",这些例子使用Condition对象的signalAll(),而不获取与该Condition相关的锁。

令人惊讶的是,我在本书的勘误表中没有找到这些示例的任何修复方法。此外,他们建议对图8.12的FifoReadWriteLock的例子进行更正,但他们继续使用没有锁的signalAll()。这让我感到不安,我试图找到有关这些示例的其他考虑因素,以了解以这种方式编写这些 Java 示例的原因。

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

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

关于没有锁采集,您可以阅读两个不同的原因:

  1. 仅将其用作伪代码
  2. 条件变量的某些实现不需要保持锁发出信号。

很难接受第一个论点,因为这本书使用了Java中的例子,并明确指出:

本书使用了Java编程语言。

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

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

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

我不知道

JDK中有任何Condition实现允许在不同时拥有显示器的情况下等待或发出信号。

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

如果你尝试一个简单的例子 使用建议的FifoReadWriteLock ,你会发现它writeUnlock()方法会喷出大量的IllegalMonitorStateExceptions。如果应用其他方法中的锁定尝试最终方法,则这些异常将消失。

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

相关内容

  • 没有找到相关文章

最新更新