java - 当正在等待的线程收到通知时,另一个线程是否可以进入监视器?

标签 java concurrency

我正在研究 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/

相关文章:

java - 更新 SQLite Android 时出错

java - Java 8 流中的本地存储

java - 在java线程之间移交控制权

java - ConcurrentLinkedQueue 上的迭代器不会迭代到下一个值

python - 我应该为仅存在于 {class,method} 中的变量使用线程本地存储吗?

java.lang.AssertionError : in Mockito. 如何解决?

concurrency - Cassandra 中的柜台设计

mysql - UPDATE.. WHERE... - 交易可以在两者之间发生吗

jakarta-ee - jboss 是否为我处理托管实体管理器并发问题?

java - Java 是否存在像 CHESS 这样的东西?