操作系统设置是否会影响ExecutorService?

时间:2018-07-25 11:05:34

标签: java multithreading linux-kernel executorservice

是否存在任何可能影响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 /内核设置,因为该服务器是出于某些特殊目的。但我不熟悉这些设置。

我想在更改工作线程之前有一个大数字可能是一个提示,但找不到答案。

任何建议将不胜感激。

3 个答案:

答案 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调度策略将是另一回事,但是我能够从中得到我想要的答案。