我读过Java线程是用户级线程,用户级线程和内核级线程之间的区别之一是内核级线程由内核调度(我们无法更改它),而对于用户级线程,我们可以定义我们的自己的调度算法。
那么我们如何在 Java 中调度线程呢?在任何给定时间,当多个线程准备好执行时,运行时系统会选择Runnable
具有最高优先级的线程执行。如果两个具有相同优先级的线程正在等待 CPU,调度程序会选择其中一个以循环方式运行。如果我不想要 RR 怎么办?有什么办法可以改变它还是我在这里遗漏了什么?
我读过Java线程是用户级线程,用户级线程和内核级线程之间的区别之一是内核级线程由内核调度(我们无法更改它),而对于用户级线程,我们可以定义我们的自己的调度算法。
那么我们如何在 Java 中调度线程呢?在任何给定时间,当多个线程准备好执行时,运行时系统会选择Runnable
具有最高优先级的线程执行。如果两个具有相同优先级的线程正在等待 CPU,调度程序会选择其中一个以循环方式运行。如果我不想要 RR 怎么办?有什么办法可以改变它还是我在这里遗漏了什么?
您不能更改调度算法,因为 JVM 这超出了范围。JVM 使用底层操作系统提供的用户线程的线程。
因此,从 Java 的角度来看,您无法更改调度算法。调度是自动完成的。
在 Java 中,您唯一能做的就是设置线程的优先级。但是没有定义这如何影响调度算法。
您可以尝试更改运行 VM 的操作系统的调度算法。但这高度依赖于所使用的操作系统。
在过去 10 年左右的时间里,JVM 线程是系统级线程,而不是用户级(“绿色”)线程。即使对于用户级线程,您也无法管理它们(JVM 可以)。
JVM 规范没有说明实现应该如何调度线程。Hotspot VM(很可能几乎所有其他实现也是如此)使用操作系统调度机制(如 Uwe 所述)。另请参阅什么是 JVM 调度算法?.
影响应用程序线程调度的一种简单但最可能不是非常有效的方法是只有 n 个可运行线程供操作系统调度(n 是您实际希望并行运行的线程数)。例如,这可能是您自己的 ExecutorService 实现,它使您不想被操作系统调度的所有线程等到您认为它们应该运行。当然,这样你就不会对其他 VM 线程产生任何影响,更不用说其他应用程序或操作系统了。
更多涉及(而不是独立于平台)是将操作系统调度程序本身更改为更适合 JVM 需求的东西。一个快速的谷歌研究发现了这个摘要,我想在这个领域还有更多的工作要做。
在 Effective Java,第 2 版中,Joshua Bloch 专门讨论了线程调度。他详细介绍了如何尝试调整线程调度通常只会导致解决方案依赖于 JVM 实现、不可移植和脆弱。
如果你有一个特定的调度问题,那么对于新代码你不应该处理低级线程调用。Java 具有更高级别的并发库,可以简化其中的许多任务。与其用线程定义问题的解决方案,不如考虑 Executors 和 Tasks。还有一些更高级别的工具可以简化线程间通信,例如 CountDownLatch。
低级线程调用(例如等待、通知和 notifyAll)可能很难正确执行。