好吧,我错了-下面的陈述不适用于我的测试运行中。



这封邮件(来自Java Thread邮件列表的wot, no chickens?)很旧,实际上是从1996年9月25日开始。PeterWelch发现:


  随附的演示表明已通知的线程确实得到
  放在队列的后面以便重新获得监视器。之前
  等待方法返回,使线程再次在
  监视器(在第一次通过后很久才到达的线程后面
  该队列!)。这可能导致无限超车,因此,
  线程饥饿。


再次总结行为:

Thread-1 acquires the monitor lock
Thread-1 sees the condition is not true yet -> wait()
Thread-0 acquires the monitor lock
Thread-2 contends with Thread-0 for the monitor lock
Thread-3 contends with Thread-0 for the monitor lock
Thread-4 contends with Thread-0 for the monitor lock
Thread-5 contends with Thread-0 for the monitor lock
Thread-0 turns the condition to true -> notifyAll();
Thread-0 released the monitor lock
Thread-4 acquires the monitor lock
Thread-4 enjoys his desirable state
Thread-4 releases the monitor lock
Thread-2 acquires the monitor lock
Thread-2 enjoys his desirable state
...


该线程是第一个等待条件的线程,它将永远不会是第一个重新获得监视器的线程。我已经知道,没有公平保证。但是,对我而言,新奇的是,线程如何重新获得监视器具有某种顺序。

为什么第一个线程应该成为重新获得监视器锁定的线程? Thread-1的实现方式永远无法通过条件并进入所需状态。

对于这种语义是否有一些解释?

重要提示:这个问题与我是否可以依靠发现的机制无关。我知道如何记录Java的等待和信令,并且清楚地说明了这一点,您不能依靠它。我感兴趣的是,虚拟机是否以这种方式实现,是否以某种方式对线程进行排序。

最佳答案

如果您使用对象的等待/通知,则顺序将特定于JVM。 notify方法的javadoc指出:

Wakes up a single thread that is waiting on this object's monitor. If any threads are
waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and
occurs at the discretion of the implementation. A thread waits on an object's monitor by
calling one of the wait methods.


但是,ReentrantReadWriteLock确实支持公平政策,公平模式描述为:

When constructed as fair, threads contend for entry using an approximately arrival
order policy. When the currently held lock is released either the longest-waiting
single writer thread will be assigned the write lock, or if there is a group of reader
threads waiting longer than all waiting writer threads, that group will be assigned the read lock.

09-12 09:34