Java スレッドの優先順位
Thread クラスでは、次の属性を使用して優先度を表します。
private int priority;
setPriority(int newPriority) を通じて新しい優先順位を設定し、getPriority() を通じてスレッドの優先順位を取得できます。
次の例からいくつかの情報が結論を導き出します。Java スレッドのデフォルトの優先順位は 5 です。
public static void main(String[] args) { Thread thread = new Thread(); System.out.println(thread.getPriority()); } // 打印结果:5
実際、これは完全に間違っています。表面を見ただけです。次の例を見てください。現在のスレッドの優先順位を 4 に変更し、子スレッドの優先順位が 4 であることがわかりました。 4も。
public static void main(String[] args) { Thread.currentThread().setPriority(4); Thread thread = new Thread(); System.out.println(thread.getPriority()); } // 打印结果:4
これはひどいことです。スレッドのデフォルトの優先度が 5 の場合、優先度を設定せずに新しく作成されたスレッドのスレッドは 5 になるはずですが、実際には 4 になっています。スレッド初期化優先度のソースコードを見てみましょう。
Thread parent = currentThread(); this.priority = parent.getPriority();
スレッドのデフォルトの優先度は、親スレッドの優先度を継承することがわかりました。上記の例では、親スレッドの優先度を 4 に設定しているため、子スレッドの優先度はも4になります。
厳密に言えば、子スレッドのデフォルトの優先度は親スレッドと同じで、Java メインスレッドのデフォルトの優先度は 5 です。
Java では、最低優先度 (1)、通常優先度 (5)、最高優先度 (10) の 3 つの優先度が定義されており、コードは次のようになります。 Java の優先順位の範囲は [1, 10] であり、他の数値の優先順位を設定すると IllegalArgumentException 例外がスローされます。
/** * The minimum priority that a thread can have. */ public final static int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public final static int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public final static int MAX_PRIORITY = 10;
次に、スレッド優先度の役割について説明します。まず次のコードを見てみましょう。コード ロジックは、優先度 1 のスレッド 1000 個、優先度 5 のスレッド 1000 個、優先度 10 のスレッド 1000 個の 3000 個のスレッドを作成することです。 minTimes を使用して 1000 個の MIN_PRIORITY スレッドの実行時タイムスタンプの合計を記録し、normTimes を使用して 1000 個の NORM_PRIORITY スレッドの実行時タイムスタンプの合計を記録し、maxTimes を使用して 1000 個の MAX_PRIORITY スレッドの実行時タイムスタンプの合計を記録します。各優先度の実行タイムスタンプの合計をカウントし、値が小さいほど優先度が高くなります。実行して見てみましょう。
public class TestPriority { static AtomicLong minTimes = new AtomicLong(0); static AtomicLong normTimes = new AtomicLong(0); static AtomicLong maxTimes = new AtomicLong(0); public static void main(String[] args) { List<MyThread> minThreadList = new ArrayList<>(); List<MyThread> normThreadList = new ArrayList<>(); List<MyThread> maxThreadList = new ArrayList<>(); int count = 1000; for (int i = 0; i < count; i++) { MyThread myThread = new MyThread("min----" + i); myThread.setPriority(Thread.MIN_PRIORITY); minThreadList.add(myThread); } for (int i = 0; i < count; i++) { MyThread myThread = new MyThread("norm---" + i); myThread.setPriority(Thread.NORM_PRIORITY); normThreadList.add(myThread); } for (int i = 0; i < count; i++) { MyThread myThread = new MyThread("max----" + i); myThread.setPriority(Thread.MAX_PRIORITY); maxThreadList.add(myThread); } for (int i = 0; i < count; i++) { maxThreadList.get(i).start(); normThreadList.get(i).start(); minThreadList.get(i).start(); } try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("maxPriority 统计:" + maxTimes.get()); System.out.println("normPriority 统计:" + normTimes.get()); System.out.println("minPriority 统计:" + minTimes.get()); System.out.println("普通优先级与最高优先级相差时间:" + (normTimes.get() - maxTimes.get()) + "ms"); System.out.println("最低优先级与普通优先级相差时间:" + (minTimes.get() - normTimes.get()) + "ms"); } static class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { System.out.println(this.getName() + " priority: " + this.getPriority()); switch (this.getPriority()) { case Thread.MAX_PRIORITY : maxTimes.getAndAdd(System.currentTimeMillis()); break; case Thread.NORM_PRIORITY : normTimes.getAndAdd(System.currentTimeMillis()); break; case Thread.MIN_PRIORITY : minTimes.getAndAdd(System.currentTimeMillis()); break; default: break; } } } }
実行結果は次のとおりです。
# 第一部分 max----0 priority: 10 norm---0 priority: 5 max----1 priority: 10 max----2 priority: 10 norm---2 priority: 5 min----4 priority: 1 ....... max----899 priority: 10 min----912 priority: 1 min----847 priority: 5 min----883 priority: 1 # 第二部分 maxPriority 统计:1568986695523243 normPriority 统计:1568986695526080 minPriority 统计:1568986695545414 普通优先级与最高优先级相差时间:2837ms 最低优先级与普通优先级相差时间:19334ms
結果を一緒に分析してみましょう。まず最初の部分を見てみましょう. 最初に実行されるスレッドには高優先度、通常の優先度、低優先度があります. 最後に実行されるスレッドにもさまざまな優先度があります. これは次のことを示しています: 優先度が高いスレッドは必ずしも優先度が高いことを意味するわけではありません優先度の低いスレッドが最初に実行されます。言い換えることもできます。コードの実行順序はスレッドの優先順位とは関係ありません。 2 番目の部分の結果を見ると、最も高い優先度を持つ 1000 個のスレッドの実行タイムスタンプの合計が最も小さく、最も低い優先度を持つ 1000 個のスレッドの実行タイムスタンプの合計が最も大きいことがわかります。したがって、次のことがわかります。 優先度の高いスレッドのバッチは、優先度の低いスレッドのバッチよりも最初に実行されます。つまり、優先度の高いスレッドは、優先度の低いスレッドよりも CPU リソースを取得する可能性が高くなります。
各オペレーティング システムには本当に 10 のスレッド レベルがあるのでしょうか?
クロスプラットフォーム言語として、Java には 10 レベルのスレッドがありますが、異なるオペレーティング システムにマップされるスレッド優先順位の値は異なります。次に、OpenJDK のソースコードで各オペレーティング システムのスレッド優先度マッピングの値を確認する方法を説明します。
Thread のソース コードを確認すると、スレッドの優先度を設定すると、最終的にローカル メソッド setPriority0() が呼び出されます;
private native void setPriority0(int newPriority);
次に、次の Thread.c コードの setPriority0() に対応するメソッド JVM_SetThreadPriority が見つかります。 OpenJDK ;
static JNINativeMethod methods[] = { ... {"setPriority0", "(I)V", (void *)&JVM_SetThreadPriority}, ...};
JVM_SetThreadPriority に基づいて jvm.cpp 内の対応するコード セグメントを見つけます;
JVM_ENTRY(void, JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)) JVMWrapper("JVM_SetThreadPriority"); // Ensure that the C++ Thread and OSThread structures aren't freed before we operate MutexLocker ml(Threads_lock); oop java_thread = JNIHandles::resolve_non_null(jthread); java_lang_Thread::set_priority(java_thread, (ThreadPriority)prio); JavaThread* thr = java_lang_Thread::thread(java_thread); if (thr != NULL) { // Thread not yet started; priority pushed down when it is Thread::set_priority(thr, (ThreadPriority)prio); } JVM_END
手順 3 のコードに基づいて、キーがコード java_lang_Thread:: であることがわかります。 set_Priority() 、引き続き thread.cpp コード内の set_Priority() メソッドを探します;
void Thread::set_priority(Thread* thread, ThreadPriority priority) { trace("set priority", thread); debug_only(check_for_dangling_thread_pointer(thread);) // Can return an error! (void)os::set_priority(thread, priority); }
以上がJavaスレッドの優先順位の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。