是啥让线程的执行顺序不可预测?

Posted

技术标签:

【中文标题】是啥让线程的执行顺序不可预测?【英文标题】:What makes the execution order of threads unpredictable?是什么让线程的执行顺序不可预测? 【发布时间】:2011-12-16 10:50:27 【问题描述】:

是什么让线程的执行顺序不可预测?调度程序是否在某个时候使用随机数或检查系统资源或查看哪个线程已等待足够长的时间或...?

【问题讨论】:

【参考方案1】:

调度程序通常是操作系统的调度程序。它受许多因素的影响,包括机器上的其他进程正在做什么,硬件正在做什么(中断)等。根据操作系统,我想有时可能会涉及随机数,但我怀疑一般不会。更多的只是多个可变时间间隔可以重叠的不可预测的方式。

【讨论】:

【参考方案2】:

在调度程序中使用随机数会给操作系统的关键部分带来不必要的开销,因此这不太可能是原因,至少在任何主流操作系统中都是这样。

一个线程通常会一直运行,直到它发出一个会阻塞的操作系统调用,或者直到发生中断,或者直到它的时间片到期(最终只是一个定时器中断)。即使您可以仔细构建事物,以便两个线程始终以确定的顺序阻塞,您也无法准确控制后两种效果何时发生。应用程序中线程的执行顺序最终会受到应用程序外部事件的影响。

【讨论】:

【参考方案3】:

其他问题在技术细节方面很重要,但是:

确切地说,Java 中的线程调度由 lockswait/notify/notifyAllsleep 方法和其他并发方法相当有效地控制控制。 只有在应用程序执行期间,这些不存在,不同线程的执行顺序未定义

主要原因可能是为了便于 Java 在不同硬件/OS 系统中的可移植性。这也是合乎逻辑的,如果您作为开发人员没有定义应用程序中的不同线程应该使用上述并发控制执行的顺序,那么您就不会关心它,那么这无关紧要,任意方式可能是由 JVM 选择。

【讨论】:

【参考方案4】:

根据 JVM,JVM 可能会将线程按原样传输到 OS,而 OS 调度程序将调度线程,或者 JVM 可能决定自行调度线程,所以第一个区别(在 2 台不同的机器上相同的不可预测的行为情况)来了,线程是由 JVM 还是 OS 调度的,你不能确定..... 而且有很多因素,线程的优先级是一个因素(我们可以设置优先级),资源是另一个因素......不太可能涉及随机数。

【讨论】:

当前所有的主流 JVM 都将调度完全交给了操作系统。一些较旧的 JVM 使用绿色线程,但在这种情况下,所有线程调度由 JVM 管理。 @MichaelBorgwardt 我猜 SCJP 的 Java 6 书籍需要包含这个解释,他们没有在书中提到新旧 JVM 的区别!无论如何感谢您的更新【参考方案5】:

现代操作系统使用所谓的Preemtive multitasking。它保证系统上的每个进程都有一定的 CPU 时间,并有各种规则来决定何时中断每个进程并让下一个进程轮流。这就是为什么你的机器上每个进程不需要一个 CPU :)

这不是随机的,但通常是不可预测的。

【讨论】:

以上是关于是啥让线程的执行顺序不可预测?的主要内容,如果未能解决你的问题,请参考以下文章

Java中如何保证线程顺序执行

当您感兴趣的任务完成时,是啥让完成处理程序执行该块?

是啥让一些 EXIF 标签不可写?

是啥让我的模型在笔记本电脑和 colab 上运行时预测错误值?

是啥让用户定义的类不可散列?

多线程编程