是否存在任何可能影响ExecutorService执行方式的操作系统设置/选项?
在不同的操作系统下使用相同的代码,我得到了不同的结果。
ExecutorService es = Executors.newFixedThreadPool(3);
for ( int j = 0 ; j< 1000 ; j ++) {
es.execute(() -> {
String threadName = Thread.currentThread().getName();
long start = System.nanoTime();
System.out.println(threadName + "- start");
System.out.println(threadName + "- end, elapsed time:" + TimeUnit.MICROSECONDS.convert(System.nanoTime() - start, TimeUnit.NANOSECONDS));
});
}
当我从笔记本电脑(Windows)运行此代码时,得到的结果如下所示。
pool-1-thread-1- start
pool-1-thread-2- start
pool-1-thread-3- start
pool-1-thread-2- end, elapsed time:86
pool-1-thread-1- end, elapsed time:137
pool-1-thread-2- start
pool-1-thread-3- end, elapsed time:155
pool-1-thread-2- end, elapsed time:38
pool-1-thread-1- start
pool-1-thread-2- start
pool-1-thread-3- start
pool-1-thread-2- end, elapsed time:47
pool-1-thread-1- end, elapsed time:91
pool-1-thread-2- start
pool-1-thread-3- end, elapsed time:94
pool-1-thread-2- end, elapsed time:91
问题是当我在CentOS服务器中运行相同的代码时,结果却完全不同。
pool-1-thread-1- end, elapsed time:5
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:19
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-1- end, elapsed time:4
pool-1-thread-1- start
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:10382
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:4
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:4
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:4
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:5
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:4
pool-1-thread-2- start
pool-1-thread-2- end, elapsed time:4
pool-1-thread-2- start
仅供参考,我没有添加任何JVM选项。这两个设备具有相同的jdk版本。 CentOS上可能有一些异常的OS /内核设置,因为该服务器是出于某些特殊目的。但我不熟悉这些设置。
我想在更改工作线程之前有一个大数字可能是一个提示,但找不到答案。
任何建议将不胜感激。
答案 0 :(得分:1)
否,任何操作系统上都没有此类设置。 当有可用的空闲处理器时,线程会获取时间。 这进一步取决于可用的处理器数量和处理器速度。
答案 1 :(得分:0)
程序的行为(如您编写的程序)取决于:
当您更改操作系统和(可能)硬件(或虚拟硬件)平台时,程序的行为会有所不同,这一事实不足为奇。
在这种情况下将影响行为的另一种想法是如何处理System.out
的输出,以及如何影响线程调度。
可能还有一些操作系统设置可以更改调度程序的行为,但是在这种情况下,您无需查看这些内容即可解释所看到的差异。
答案 2 :(得分:0)
我有一个答案。 只是内核参数isolcpus阻止了CPU调度。
我用isolcpus锁定了CPU的某些内核以实现线程相似性,并且我通过任务集-p PID将这些孤立的内核专用于Java进程。
我不知道孤立的CPU超出了OS CPU调度的范围。最终Java进程仅在剩余的2个cpu内核上运行,这在第二种情况下会产生不同的结果。(任务集设置没有用,因为孤立的cpu已不在操作系统CPU调度范围内)
在大多数情况下,在这种情况下释放isolcpus内核参数很简单。
使用isolcpus的另一种方法是添加chrt
taskset -p 1-17 chrt -r 1 java <classPath>
选择APPT调度策略将是另一回事,但是我能够从中得到我想要的答案。