【问题标题】:How long does a Java thread own a CPU time slice?Java 线程拥有多长时间的 CPU 时间片?
【发布时间】:2020-01-17 21:13:48
【问题描述】:

每个 Java 线程都映射到 Windows 中的内核线程,在 Windows 中,线程切换的时间片为 10-100 毫秒。

但是,从以下简单代码的结果来看,似乎每个线程在每一行代码中都会切换 CPU 资源。为什么?

class MyThread extends Thread{
    public MyThread(String name){
        super(name);
    }
    public void run(){
        for(int i=0;i<5;i++){
              System.out.println( this.getName()+":"+i);
        }
    }
    public static void main(String args[]){
        Thread p = new MyThread("t1");
        p.start();
        for(int i=0;i<5;i++){
                System.out.println(    "main:"+i);
        }
    }
}

【问题讨论】:

  • 预期和实际输出是多少?另请注意:代码中最耗时的活动是打印语句。哪个都一样,有各种奇怪的效果....
  • 我很好奇你是怎么知道它根据你的例子切换 CPU 的?
  • System.out 是一个缓冲 PrintStream。执行顺序不一定是你在控制台上看到的。但是是的,每个 Java 线程都有一个由操作系统调度的本地线程。
  • 给定多个 CPU 不应该单个线程在同一个 CPU 上获得全时?
  • No @prayagupd ... 除了 Java 进程/线程,操作系统通常还有很多其他进程要调度。

标签: java multithreading operating-system


【解决方案1】:

首先,您没有告诉我们您看到了什么输出以及您期望看到什么。所以无法解释前者,或者为什么后者可能会偏离基准。

但是,有许多因素可以解释为什么输出与您的预期不同。

  • 输出可能取决于系统上的内核(或超线程)数量。以及操作系统为您的 Java 应用程序提供的数量。

  • 如果在 Java 应用程序本身或系统的其他部分中运行更高优先级的线程,则会扰乱时间切片。 (如果需要调度高优先级线程,则可以缩短低优先级线程的时间片。)

  • Java 线程重新调度不仅仅因为时间片而发生。当线程阻塞 I/O,或者它试图获取 Lock 或互斥体,或 wait(...)sleep(...) 或类似的东西时,也会发生这种情况。

  • System.out.println 在幕后进行了一些隐藏的同步,因此同时打印的两个线程不会导致共享缓冲区数据结构损坏。

简而言之,无论您从该程序中看到什么输出,都不会是时间切片行为的明确证据。 (而且我的猜测是它根本没有任何意义的证据。)


但是你的问题的答案:

Java 线程拥有 CPU 时间片多长时间?

是无法预测,也很难衡量。

【讨论】:

  • Re,“……无法预测。”可能更准确地说,“未定义”。 Java 语言规范中没有任何内容限制线程调度使用任何特定持续时间的时间片。
  • @SolomonSlow - 你的陈述和我的陈述都是 100% 准确的。但我认为我的问题更适合提出的问题。
【解决方案2】:

System.out.println 是一个阻塞操作,与您正在执行的其他操作相比,它需要花费大量时间。它也是同步的,因此一次只有一个线程可以打印一行。

这会导致您看到的交替行为。当一个线程正在打印时,另一个线程有足够的时间准备打印,调用println,并等待第一个线程完成。当第一个线程完成打印时,第二个线程开始打印,第一个线程将在完成之前返回等待它完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    相关资源
    最近更新 更多