我正在研究 Java 并发性,并且发现了一个我无法回答的有趣问题。
例如,我有三个线程:ThreadA、ThreadB 和 ThreadC。 ThreadA 进入监视器,并调用 wait() 方法。然后ThreadB进入同一个监视器,调用notify()方法并在一段时间内继续拥有该监视器。当 ThreadB 拥有监视器时,ThreadC 也尝试获取监视器。我的问题是,当ThreadB释放监视器时,ThreadC是否可以比ThreadA更早地获取监视器?如果可以,为什么?需要满足哪些条件才能重现?
最佳答案
根据 Object.notify() 的 Javadoc:
The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
因此存在ThreadC先于ThreadA拥有监视器的可能性。任何线程进入/获取监视器的顺序都没有定义,也没有用于标准同步的任何优先级或公平机制。它真正保证的是,对于给定的锁对象,只有一个线程会同时位于同步块(synchronized block)中。
考虑到这一事实,在设计时应仔细考虑线程如何获取锁以及获取锁的时间。重复尝试获取锁(获取然后释放,然后再次获取)的线程可能会导致另一个线程无限期地被锁定(称为线程饥饿)。
将 ReentrantLock
与公平策略结合使用可以部分克服此问题,但会带来一定的性能损失(比传统同步稍慢)。
关于java - 当正在等待的线程收到通知时,另一个线程是否可以进入监视器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28605736/