Java 多线程延迟的原因

Java 多线程延迟的原因,java,multithreading,Java,Multithreading,我用Java编写了一个程序,在for循环中打印10万个 for (int i =0;i<1000000;i++){ System.out.println(i); } 我在自定义线程类中创建了10个对象,为每个对象分配了一个100k的数字块来打印,所以最后我打印了所有10万个(不一定按顺序),但大约需要9.5秒 延迟2秒的原因是什么?这是因为线程之间发生了时间切片和上下文切换吗?我正在执行一个java进程,它产生了10个线程。我想的方向对吗 更新:评论了System.out.pr

我用Java编写了一个程序,在
for
循环中打印10万个

for (int i =0;i<1000000;i++){
     System.out.println(i);
}
我在自定义线程类中创建了10个对象,为每个对象分配了一个100k的数字块来打印,所以最后我打印了所有
10万个
(不一定按顺序),但大约需要9.5秒

延迟2秒的原因是什么?这是因为线程之间发生了时间切片和上下文切换吗?我正在执行一个java进程,它产生了10个线程。我想的方向对吗


更新:评论了
System.out.println
以查看迭代时它的执行情况

没有线程的打印时间

2019-04-14 22:18:07.111   // start
2019-04-14 22:18:07.116 // end
使用ThreadCustom类:

2019-04-14 22:26:42.339
2019-04-14 22:26:42.341

额外的时间用在两个方面: 1) 设置每个线程执行上下文所涉及的开销 2) 可能的情况是,您正在生成的线程数超过了主处理器中可用的逻辑处理器数

由于增加循环和打印整数所需的处理量是最小的,因此在大多数情况下,这将导致并行环境中的性能下降

但是,如果您在每次迭代期间对任何给定图像上的不同像素颜色进行计数,那么在使用多个线程时,您将看到显著的性能优势

我用Java编写了一个程序,在for循环中打印[100万]。。。我创建了10个自定义线程类的对象。。。但大约需要9.5秒。延迟2秒的原因是什么

只有当线程能够独立工作时,线程才会更快。在将数字打印到
System.out
的情况下,所有线程都试图争夺对同一资源
System.out
的访问权,这是一个同步的
PrintStream
。这意味着大部分时间都浪费在等待另一个线程释放
System.out
上的锁上。线程程序的任何额外“延迟”最有可能是由于锁争用和线程之间的上下文切换

为了适当地测试线程速度,您需要在每个线程中运行某种独立的CPU任务。计算
Math.sqrt(…)
多次是一个更好的例子。在我较新的Macbook上,我可以在大约8.1秒内完成10亿次(使用b)
Math.sqrt(…)
调用,但10个线程可以在大约1.1秒内并行完成1亿次。但是等等,你可能会说,10*1.1>8秒的总CPU。我有4个内核,所以有10个线程在运行,有很多CPU的进出。4个线程完成250m每个需要2.1秒,这与单线程示例中的8.1秒非常接近


最后,Java性能测试非常困难。我打赌如果你运行两个程序多次,你会看到一些不同的结果。任何快速运行的程序都不能很好地判断速度,或者充其量只是一个非常粗略的近似值。此外,您还需要小心,否则热交换编译器可能会在运行时优化循环,因此您需要尝试执行实际工作。

我的第一个猜测是,在尝试执行输出时,一次锁定多个线程。然而,它并不是一个真正的基准。
System.out.println
是线程安全的,所以您的所有线程都经常处于争用状态。@JacobG。所以它会导致延迟,因为它允许一个线程一次使用它?@Danyalsandelo我会说是的,因为在给定的时间只有一个线程可以打印。我假设同步开销是造成延迟的原因。欢迎您随时乐意提供帮助,无论以何种方式提供帮助;-)谢谢你的解释。我删除了System.out.println,并且统计数据已经更改。线程1在我检查的所有运行中都很快完成。因此,基本上,线程在多个处理器上分别执行。
2019-04-14 22:26:42.339
2019-04-14 22:26:42.341