Java线程优先级如何转换为操作系统线程优先级?

9

Java API线程优先级(1-10)如何转换为操作系统级别的优先级,因为大多数操作系统没有与此匹配的线程优先级(以数字表示)。

因此,请记住,是否可能存在这样的情况:两个或多个具有不同优先级的线程最终在操作系统级别获得相同的优先级。

请澄清一下,如果我对理解有所纠正。

4个回答

14

确实,某些优先级可以映射到相同的“本机”优先级。以下是列表(基于OpenJDK 6中Hotspot代码):

Solaris

  • 1 ⇒ 0
  • 2 ⇒ 32
  • 3 ⇒ 64
  • 4 ⇒ 96
  • 5 – 10 ⇒ 127

值得注意的是,在Solaris上,您无法将线程优先级提高到以上正常水平,只能将其降低:5的优先级值与更高值相同。

Linux

  • 1 – 10 ⇒ 4 – -5(nice值)

值得注意的是,在Linux上,Java中的不同线程优先级确实映射到本机级别的不同优先级值。

Windows

  • 1 – 2 ⇒ THREAD_PRIORITY_LOWEST
  • 3 – 4 ⇒ THREAD_PRIORITY_BELOW_NORMAL
  • 5 – 6 ⇒ THREAD_PRIORITY_NORMAL
  • 7 – 8 ⇒ THREAD_PRIORITY_ABOVE_NORMAL
  • 9 – 10 ⇒ THREAD_PRIORITY_HIGHEST

你手头有这方面的参考资料吗?这是直接映射还是基于操作系统处理这些值的仿真? - Dana the Sane
1
虽然没有官方文档,但是在OpenJDK源代码的hotspot/src/os/{linux,solaris,win32}/vm/os_{linux,solaris,win32}.cpp中阅读(搜索java_to_os_priority)可以找到这些值。 :-) - C. K. Young
1
它也在这里有详细的说明:http://www.javamex.com/tutorials/threads/priority_what.shtml - Guillaume

1

你的理解是正确的 - Java线程优先级与操作系统线程优先级并不完全对应。

因此,如果你的算法在任何方面依赖于线程优先级映射的细节,那么它就是有问题的,因为它会根据许多变量而变化。例如,升级JRE或将补丁/服务包应用于操作系统可能会破坏它 - 当然,在不同的操作系统上运行也会产生后果。

除非是非常特殊的情况,否则只使用两个优先级就足够了 - 正常和低。大部分工作将在正常线程中完成。低优先级应该保留给不能允许饥饿正常优先级线程的线程,而只是吞噬其他未被使用的处理器资源。

虽然你可以选择更细致的设置,但你需要知道任何更详细的设置都可能会在目标平台上丢失。


1

我对Linux上的Sun JVM不是很确定。我写了一个快速的Java程序,用每个优先级生成10个线程,并使用BigDecimals计算pi(4 * atan(1)方法)500,000次,然后在每个线程上进行join并报告运行方法的经过时间。是的,可能不是最好的例子,但保持基本。

$uname -r && grep bogomips /proc/cpuinfo
2.4.33.3
bogomips        : 4312.26
$java -version 2>&1 |head -1
Java version "1.6.0_01"
$javac T.java && java -Xmx32m T
1:3112
2:2636
3:2662
4:3118
5:2870
6:3319
7:3412
8:3304
9:3299
10:3069

看起来并没有人们所期望的那么大的偏差!这是在一个小型虚拟Linux机器上测试的。为了确保,让我们在一台真实的服务器上试试,这个服务器非常活跃,负载平均值很少低于7,让我们看看在这样的环境中如何进行调度:

$uname -r && grep bogomips /proc/cpuinfo
2.6.9-67.ELsmp
bogomips        : 3992.93
bogomips        : 3990.00
$java -version 2>&1 |head -1
java version "1.4.2_14"
$javac T.java && java -Xmx32m T
1:63200
2:64388
3:62532
4:58529
5:62292
6:64872
7:64885
8:64584
9:61653
10:61575

程序相关:

这里没有太多变化,不知道1.4版本是否映射了线程。让我们尝试一下Windows系统。我知道Windows有一个相当激进的线程优先级模式。任何高于normal的选项据说会消耗更多资源。因此,让我们将每个线程的迭代次数增加到900,000:

C:\>java -version
java version "1.6.0_11"
C:\>java -Xmx32m T
1:12578
2:12625
3:11469
4:11453
5:10781
6:8937
7:10516
8:8406
9:9953
10:7391

这正是我们正在寻找的,不是吗?


-1

既然我们正在谈论线程,我认为这不会直接影响操作系统。优先级可能是提示JRE如何安排每个线程的CPU时间的线索。要处理您的示例,需要某种“打破平局”的算法。

基本上,这将在操作系统进程优先级之上,除非JRE使用第三方线程标准(例如POSIX)而不是在内部实现所有内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接