我一直在阅读《Head First》中的多线程。我对多线程的了解是:
当我们使用 Thread 类的对象调用 start() 时,线程将进入 Runnable 状态。因此,所有线程在通过这些线程的对象调用 start() 后都会进入 Runnable 状态。它是 JVM 线程调度程序,它从 Runnable 状态中随机挑选线程,使其处于 Running 状态。进入“运行”状态后,将执行该特定线程的确定的调用堆栈。 同样,JVM 线程调度程序可以通过将线程从“运行”状态切换到“可运行”状态来停止线程的执行。这次,代码执行在该线程的调用堆栈中暂停。
现在我的问题是,对于多处理器机器,JVM线程如何 调度程序从 Runnable 状态选择线程?是否只选择一个 线程并将其交给处理器?或者,它是否选择了多个 线程并将这些线程赋予不同的运行状态 处理器?
我写了下面的代码:
// Class of main thread
public class ThreadMain {
public static void main(String[] args) {
Runnable threadJob=new MyRunnable();
Thread t=new Thread(threadJob);
t.start();
System.out.println("Back in the Main");
}
}
// Class of another thread
public class MyRunnable implements Runnable{
public void run()
{
System.out.println("I'm Thread");
}
}
这里有两个线程。主线程,以及我创建的线程。如果我的机器有多处理器,它会如何表现? JVM 线程调度程序是否会一次选择两个线程,并将它们分配给两个处理器?
在当今的大多数实现中,JVM 将为每个 Java
平台线程创建一个操作系统级线程,并让操作系统进行调度。从 Java 21 开始,还有由 JVM 管理但在平台线程之上运行的“虚拟线程”,这仍然将抢占式调度留给了操作系统。但是特定的 JVM 实现可能包含一个抢占式调度程序,适用于没有抢占式调度程序的操作系统。 例如,Sun 的 JVM 就是上个千年的情况。此时,可以选择使用“绿色线程”,而不是本机线程。请注意,这些在没有操作系统帮助的情况下实现的线程无法使用多个 CPU/核心。 因此,在实践中,当您运行示例程序时,操作系统的调度程序确实可能会将第二个线程分配给不同的核心。然而,由于这是一个很小的程序,第一个线程也有可能在第二个线程开始实际工作之前终止,在这种情况下,它可能会在与第一个线程相同的核心上运行,但不能保证任何完全有特定的调度行为。
虽然无法保证特定的调度行为,但大多数 SMP 库和工具都是基于(有根据的)假设构建的,即如果有足够的可运行线程和足够的工作负载,底层系统会将这些线程分配给可用的 CPU 核心。
正如其他人正确回答的那样,JVM 使用底层操作系统(在我的例子中是 Windows 10)来管理线程。 Windows 操作系统将进行抢占式(基于优先级)调度。如果存在多个具有最高优先级的线程,Windows 将为线程使用基于循环的时间切片调度。
(参考:-
https://learn.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities要回答有关多处理器系统(此处再次将 Windows 称为操作系统)的具体问题,这取决于此类系统所使用的架构。通常有两种类型的架构
SMP - 对称多处理
(参考:-
https://learn.microsoft.com/en-us/windows/win32/procthread/multiple-processors)。
希望这有帮助!干杯!!
JVM 使用底层操作系统(Unix、Windows 等)线程机制在多处理器系统上调度 Java 线程。