wait(),notify() - 哪个线程首先解锁?

时间:2016-11-05 10:10:55

标签: java multithreading java-threads

尝试理解wait()notify()。我知道线程A何时转到wait(),它将被notify()从其他线程中唤醒。

但是如果线程ABC以代表顺序转到wait()会发生什么?谁将被notify()惊醒?根据我的实验A线程将首先被唤醒。我没错?

这是否意味着系统知道线程转到wait()的顺序?

5 个答案:

答案 0 :(得分:7)

notify()的文档中强调我的:

  

唤醒正在此对象监视器上等待的单个线程。 如果有任何线程正在等待此对象,则会选择其中一个线程进行唤醒。选择是任意的,由实现自行决定。线程通过调用其中一个等待方法等待对象的监视器。

其他一些API,例如Semaphore,具有“公平”的概念,您可以确保线程 按照它们阻止的顺序进行。

答案 1 :(得分:2)

Java语言规范的17.2.2 Notification部分:

  

无法保证等待集中的哪个线程被选中。

因此,观察到的行为不能保证,不应该依赖。

答案 2 :(得分:2)

不,VM不知道线程处于等待状态的顺序。

当你调用notify()时,其中一个将返回Alive / Runnable状态,并且无法知道VM将选择哪一个。

有时它们可​​以按照处于等待状态的顺序运行,但规范并不保证。因此,如果您多次运行代码,在不同的VM中,您可以获得完全不同的结果,甚至可以在同一个VM中。

答案 3 :(得分:1)

不,订单无法保证。 notify方法的javadoc非常清楚:

  

唤醒正在此对象监视器上等待的单个线程。如果任何线程正在等待此对象,则选择其中一个线程被唤醒。 选择是任意的,由实施决定。线程通过调用其中一个等待方法等待对象的监视器。

答案 4 :(得分:1)

没有这样的订单。两个线程都有平等的机会进入 runnable 状态。实际上JVM / OS只能将它们视为一组等待线程,它们不知道任何顺序。

就您的实验而言,为了得出一个公平的结论,实际上您必须执行很多次。

在线程中,只有当您使用strong Semaphore之类的东西时,才能获得订单(FIFO)。然后将这些线程放入等待队列,并首先提供拳头。