java - JVM 线程调度程序如何控制多处理器的线程?

标签 java multithreading jvm

我一直在阅读关于多线程的《深入浅出》。我对多线程的了解是:

当我们使用 Thread 类的对象调用 start() 时,该线程会进入 Runnable 状态。因此,所有线程在调用这些线程的对象start() 后进入Runnable 状态。它是 JVM 线程调度程序,它从 Runnable 状态随机选择线程,使其处于 Running 状态。在进入Running 状态后,为该特定线程确定的调用堆栈将被执行。

同样,JVM 线程调度程序可以通过将线程从 Running 状态切换到 Runnable 状态来停止线程的执行。这一次,代码执行在该线程的调用堆栈中暂停。

Now my question is, for multiprocessor machine, how JVM thread scheduler picks thread from the Runnable state? Does it pick only one thread and give it to a processor? Or, does it pick more than one thread and give those threads to Running state of different processors?

我写了下面的代码:

// 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 和类库视为一个整体的执行环境时,术语“JVM 线程调度程序”才有意义。然后,保证这个环境有一个调度器,不管它是如何实现的。

在当今的大多数实现中,JVM 将为每个 Java 线程创建一个操作系统级别的线程,并且本身不执行任何 Activity 的调度 Activity 。但是特定的 JVM 实现可能包含用于操作系统的调度程序,而这些操作系统没有调度程序。

例如,对于上个千年的 Sun 的 JVM 来说就是这种情况。这时候就有了使用green threads的选项,与 native 线程相反。请注意,这些在没有操作系统帮助的情况下实现的线程无法使用多个 CPU/内核。

因此在实践中,当您运行示例程序时,操作系统的调度程序可能确实将第二个线程分配给不同的核心。但是,由于这是一个小程序,第一个线程甚至可能在第二个线程开始其实际工作之前就终止了,在这种情况下,它可能会与第一个线程在同一个内核上运行,但不能保证任何完全没有特定的调度行为。

虽然没有关于特定调度行为的保证,但大多数 SMP 库和工具都建立在(有根据的)假设之上,即如果有足够的可运行线程和足够的工作负载,底层系统会将这些线程分配给可用的 CPU 内核.

关于java - JVM 线程调度程序如何控制多处理器的线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41759261/

相关文章:

java - 如何更改 LayerDrawable 中一张图像的大小

java - 在 Hibernate 实体持久化期间发生巨大的内存泄漏,为什么?

c++ - 静态无功能线程安全吗?

java - 并发标记清除 (CMS) 卸载类中的对象类

scala - 从专业类中获取 ClassTag

java - Spring 3 宠物诊所示例使用 ${owner.new},在 JSTL EL 中,我在哪里可以阅读有关 .new 运算符的信息?

java - 我的比较器没有正确排序这个 PriorityQueue?

c# - 如何将方法限制为 n 个并发调用

java - run 方法内的同步块(synchronized block)

java - 是否可以在运行时禁用 `-XX:+PrintCompilation` 和 `-verbose:gc"`?