ほとんどのOSにはこれに一致するスレッド優先度レベル(数の点で)がないため、Java APIスレッド優先度(1〜10)はどのようにOSレベルの優先度に変換されますか。
したがって、優先順位の異なる2つ以上のスレッドが最終的にOSレベルで同じ優先順位を取得するシナリオが存在する可能性があることに注意してください。
理解に訂正がある場合は、明確にしてください。
ほとんどのOSにはこれに一致するスレッド優先度レベル(数の点で)がないため、Java APIスレッド優先度(1〜10)はどのようにOSレベルの優先度に変換されますか。
したがって、優先順位の異なる2つ以上のスレッドが最終的にOSレベルで同じ優先順位を取得するシナリオが存在する可能性があることに注意してください。
理解に訂正がある場合は、明確にしてください。
実際、一部の優先度レベルは、同じ「ネイティブ」優先度レベルにマップできます。リストは次のとおりです (OpenJDK 6 の Hotspot コードに基づく)。
注意すべき点として、Solaris では、スレッドの優先度を通常より高くすることはできず、低くすることしかできません。5 の優先度の値は、より高い値のいずれかと同じです。
nice
値)Linux では、Java のさまざまなスレッド優先度が、ネイティブ レベルで個別の優先度値にマップされることに注意してください。
THREAD_PRIORITY_LOWEST
THREAD_PRIORITY_BELOW_NORMAL
THREAD_PRIORITY_NORMAL
THREAD_PRIORITY_ABOVE_NORMAL
THREAD_PRIORITY_HIGHEST
Linux上のSunJVMについてはよくわかりません。クイックJavaプログラムを作成して、各優先度で10個のスレッドを生成し、BigDecimalsでそれぞれ500,000回pi(4 * atan(1)メソッド)を計算し、各スレッドに参加して、runメソッドの経過時間を報告します。ええ、おそらく最良の例ではありませんが、それを基本的に保ちます。
$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がかなり積極的なスレッド優先スキーマを持っていることを知っています。通常の逸話を超えるものは、はるかに多くを消費します。そのため、各スレッドで最大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
私たちが探しているものは非常に多いですよね?
あなたの理解は正しいです - Java スレッドの優先順位は、OS スレッドの優先順位にきれいにマップされません。
その結果、アルゴリズムがスレッド優先度マッピングの詳細に何らかの形で依存している場合、非常に多くの変数に応じて変化するため、アルゴリズムは壊れています。たとえば、JRE をアップグレードしたり、OS にパッチ/サービス パックを適用したりすると、それが壊れる可能性があります。もちろん、別の OS で実行するだけでも結果が生じます。
非常にまれなケースを除いて、Normal と Low の 2 つの優先度のみを使用するだけで十分です。ほとんどの作業は通常のスレッドで行われます。低優先度は、通常の優先度のスレッドを枯渇させてはならないスレッド用に予約する必要があります。
必要に応じて、これよりも細かくすることもできますが、ターゲット プラットフォームでは詳細が失われる可能性があることに注意する必要があります。
スレッドの話なので、これが直接OSに届くことはないと思います。優先順位はおそらく、各スレッドの CPU 時間をスケジュールする方法に関する JRE へのヒントです。あなたの例に対処するには、ある種の「タイブレーク」アルゴリズムが必要です。
基本的に、JRE がすべてを内部で実装するのではなく、POSIX などのサードパーティのスレッド標準を使用していない限り、これは OS プロセスの優先順位の上位になります。