Java:等待同步块,谁先去?

Java:等待同步块,谁先去?,java,multithreading,jvm,scheduling,Java,Multithreading,Jvm,Scheduling,这个问题的灵感来自 如果多个线程正在等待一个synchronized块,并且锁变为可用,那么谁先去?是否按线程优先级(然后先到先得) 对于notify(具有多个waiting线程)是否也适用相同的规则?对于第二个问题 他们中的一个被选中被唤醒。选择是任意的,由实现自行决定。线程通过调用一个wait方法在对象的监视器上等待 From()根据这个家伙的说法: Java对序列没有任何保证。所以我猜它不是基于线程优先级的 我将尝试进一步了解Java实际上是如何决定谁先走的。这取决于线程优先级和线程调度算

这个问题的灵感来自

如果多个线程正在等待一个
synchronized
块,并且锁变为可用,那么谁先去?是否按线程优先级(然后先到先得)


对于
notify
(具有多个
wait
ing线程)是否也适用相同的规则?对于第二个问题

他们中的一个被选中被唤醒。选择是任意的,由实现自行决定。线程通过调用一个wait方法在对象的监视器上等待

From()

根据这个家伙的说法:

Java对序列没有任何保证。所以我猜它不是基于线程优先级的


我将尝试进一步了解Java实际上是如何决定谁先走的。

这取决于线程优先级和线程调度算法,而且同步块上的锁也不“公平”。这意味着,如果有两个具有相同优先级的等待线程,并且第一个线程的等待时间比第二个线程的等待时间长,这并不一定意味着第一个线程将首先执行。

其他人提到了公平锁的可用性。如果你真的在乎谁先走,那么你可能会遇到实时性问题。在这种情况下,可以使用RTSJ,其中指定了锁获取的顺序和其他语义。有关详细信息,请参见“同步”下的。引述理由部分:

Java的同步代码规则 提供相互排斥的手段 但不要阻止无限优先级 因此,反转和反转是不够的 用于实时应用程序。这 规范加强了 同步代码的语义 强制执行优先级反转控制, 特别是通过提供课程 优先继承和优先权 天花板模拟。优先 继承被更广泛地实现 在实时操作系统和 因此,这是必需的,也是初始的 这方面的默认机制 规格


知道Hotspot是如何处理这个问题的吗?如果我把这两个答案与线程优先级结合在一起,那么Linux上的操作系统线程优先级就不会产生影响(至少在大多数情况下是如此),这些优先级似乎没有多大作用…@Thilo,这取决于实现。我不能说这取决于操作系统。@Thilo,你打算根据行为编写代码吗?我实际上相信它也取决于操作系统,因为除了少量的自旋锁定(可能是10000次尝试或10次尝试)之外,它会让操作系统进一步处理它。+1有趣。事实证明,并发包中的锁有一个可选的公平模式,在这种情况下,它们可以fifo工作。如果不是,那就是武断。我认为线程优先级应该在这里发挥作用。我同意这是“自然”的选择。公平是有代价的,可预测性是以吞吐量大幅下降为代价的。此外,公平性要求还将阻止VM在实现锁获取时可能进行的大量优化(如瘦旋转锁等)。关于这一点的一个问题是:如果thread1是监视器的持有者,而其他线程正在等待,thread1是否可以解锁并“四处”竞争在任何已经等待的线程之前再次获得锁?@dmansfield我不能给出任何明确的答案,但我的代码中似乎就是这样。如果有人有更正式的答案,我想听听。你是说更高的优先级确实是第一位的吗?不,对不起,我没有这么说,我错过了那个案子。我是说,由于公平性,即使是优先级较高的线程也可以在优先级较低的线程之后执行。这是因为不公平的锁提供了较弱的活动性保证,要求所有线程最终获得锁。锁是不公平的,高优先级线程比低优先级线程更可能成功获得锁的唯一方式是低优先级线程本身缺乏执行时间。如果“公平”锁是您要查找的,然后查看java.util.concurrent包。例如,可重入锁定是公平的。公平性来自这样一个事实,即优先级被赋予等待时间最长的线程,类似于进程调度中的“老化”概念。