Javaスレッドの優先順位を学び、また対応するオペレーティングシステムの優先順位を知っている、またはあなたがピットを踏むだろう

Javaのマルチスレッドシリーズの第6章。

のは、この優先度のJavaスレッドを見てみましょう。

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である見つけました。

public static void main(String[] args) {
    Thread.currentThread().setPriority(4);
    Thread thread = new Thread();
    System.out.println(thread.getPriority());
}

// 打印结果:4
复制代码

彼女の顔に、この性交セッション、およびスレッドのデフォルトの優先度が5で、新しく作成されたスレッドスレッド、優先順位を設定しなかった場合は、5のはずが、実際は4です。我々は見てThread初期化priorityソースコードを。

Thread parent = currentThread();
this.priority = parent.getPriority();
复制代码

これは、スレッドのデフォルトの優先度は、親スレッドの優先順位は4となっている私たち親スレッドの優先順位は、サブ優先度のスレッドで、その結果、4に設定されている上記の例を継承していることが判明しました。

正確なポイントその子スレッドのデフォルトの優先順位とは、親スレッドのように、Javaのメインスレッドのデフォルトの優先度は5です。

Javaは、優先度の3種類の定義では、それぞれ最低优先级(1)、、 正常优先级(5)最高优先级(10)コードは以下の通りです。範囲の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優先順位、スレッドの優先順位1000年5、糸10 1000優先:コード・ロジック3000、すなわちスレッドを作成し、次のコードを見てください。使用minTimes1000のに記録しMIN_PRIORITYたスレッド実行中のタイムスタンプを使用し、normTimes1000のに記録しNORM_PRIORITYたスレッド実行中のタイムスタンプを使用し、maxTimes1000年に記録し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
复制代码

我々は結果を分析するために一緒に働きます。:最初の部分を見てみましょう、優先度の高いスレッド、通常の優先度、低優先度はほとんどが最後にも説明している、さまざまな優先順位を持って実行したスレッドを開始している優先度の高いスレッドが必ずしも比率を意味するものではありません低優先度のスレッドの実行優先順位それは別の方法で変更された可能性があります:コードの実行は、スレッドの優先順位とは何の関係もありません第二部の結果を見て、我々は1000の最も優先度の高いスレッドの実行のタイムスタンプと1000の最小、最低の優先度のスレッドの実行のタイムスタンプと最大値を見つけることができますので、あなたは学ぶことができます:高い優先度の数を低優先度のスレッドの数よりもスレッドの実行優先度、その優先順位の低いスレッドより優先度の高いスレッド優先アクセス高確率CPUリソース

各オペレーティングシステムは本当に10件のスレッドグレードのですか?

クロスプラットフォームのJava言語のように、スレッドは、10のレベルを有するが、異なるオペレーティング・システム・スレッドの優先順位値が同じではないにマッピングされました。次に、あなたに教える方法をOpenJDK、各オペレーティング・システムのスレッドの優先順位マッピングのソースコードのチェック値。

  1. 参照してくださいスレッドのスレッドの優先順位は、ローカルメソッドを呼び出して終了し、ソースコードをsetPriority0()
private native void setPriority0(int newPriority);
复制代码
  1. その後、我々はOpenJDKがThread.c見つかったコードsetPriority0()のメソッドに対応しますJVM_SetThreadPriority
static JNINativeMethod methods[] = {
    ...
    {"setPriority0",     "(I)V",       (void *)&JVM_SetThreadPriority},
    ...
};
复制代码
  1. 私たちはよる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
复制代码
  1. コードのステップ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);
}
复制代码
  1. なお、上記のコードは、最後の呼び出しであることを見出しos::set_priority()、次に識別し続けるos.cppset_priority()方法。
OSReturn os::set_priority(Thread* thread, ThreadPriority p) {
#ifdef ASSERT
  if (!(!thread->is_Java_thread() ||
         Thread::current() == thread  ||
         Threads_lock->owned_by_self()
         || thread->is_Compiler_thread()
        )) {
    assert(false, "possibility of dangling Thread pointer");
  }
#endif

  if (p >= MinPriority && p <= MaxPriority) {
    int priority = java_to_os_priority[p];
    return set_native_priority(thread, priority);
  } else {
    assert(false, "Should not happen");
    return OS_ERR;
  }
}
复制代码
  1. 最終的に、オペレーティング・システムの優先コードの最終的な変換を発見しjava_to_os_priority[p]、次のステップは、様々なオペレーティング・システムの下でアレイの値を見つけることです。たとえば、次のとおりであるLinuxの優先順位の値システム。
int os::java_to_os_priority[CriticalPriority + 1] = {
  19,              // 0 Entry should never be used

   4,              // 1 MinPriority
   3,              // 2
   2,              // 3

   1,              // 4
   0,              // 5 NormPriority
  -1,              // 6

  -2,              // 7
  -3,              // 8
  -4,              // 9 NearMaxPriority

  -5,              // 10 MaxPriority

  -5               // 11 CriticalPriority
};
复制代码

まあ、我々は[1,10]の優先順位の値は、各オペレーティングシステムに対応したJavaスレッドの優先度を見つける方法を知っている必要があります。我々は、統計を見て下に。

Javaスレッドの優先順位 Linuxの ウィンドウズ 林檎 BSD Solarisの
1 4 THREAD_PRIORITY_LOWEST(-2) 27 0 0
2 3 THREAD_PRIORITY_LOWEST(-2) 28 3 32
3 2 THREAD_PRIORITY_BELOW_NORMAL(-1) 29 6 64
4 1 THREAD_PRIORITY_BELOW_NORMAL(-1) 30 10 96
5 0 THREAD_PRIORITY_NORMAL(0) 31 15 127
6 -1 THREAD_PRIORITY_NORMAL(0) 32 18 127
7 -2 THREAD_PRIORITY_ABOVE_NORMAL(1) 33 21 127
8 -3 THREAD_PRIORITY_ABOVE_NORMAL(1) 34 25 127
9 -4 THREAD_PRIORITY_HIGHEST(2) 35 28 127
10 -5 THREAD_PRIORITY_HIGHEST(2) 36 31 127

で、WindowsのシステムのOpenJDK上記定数のみのソースを見つけるには、Microsoftが提供するインタフェースのドキュメントの機能は、この内のリンクを見つけたです:SetThreadPriority

我々はまた、実際には、設定された高優先度のスレッドよりも必ずしも低くないオペレーティングシステムスレッドにマッピングされ、我々は、Javaコード比較的高い優先度に設定した場合でも、このテーブルから問題のいくつかを見つけることができ、それはそうです同じ優先順位。見てSolarisオペレーティングシステムこの極端な例を、優先順位5-10マップは同じスレッドレベルです。

なぜ3000スレッド、上記の例に戻って考えて、MAX_PRIORITYそれを強制する優先千スレッドの優先順位?私たちの3つの優先順位がマップされているため、Windowsのように有効にするには、システムスレッドを動作させる3つの異なるレベル。1,5,10 5,6,7が変更と仮定すると、結果はほとんど同じになります。

最後に、覚えている:銀の弾丸は、優先度の高いスレッドは、必ずしも優先度の低いスレッドよりも優先しないよう、スレッドの優先順位を控えるように

このスレッドの優先順位の記事はまた、段落を報告し、私の友人は、それが役に立つ支援するトラブルのポイントを読み取るために見つける在看見るために彼女の友人にそれをお勧めして、オリジナルのは容易ではありません。

推荐阅读

Javaスレッドの優先順位を学び、また対応するオペレーティングシステムの優先順位を知っている、またはあなたがピットを踏むだろう

スレッドの最も基本的な知識

上司が詰まらないようにあなたに言いました

シリアル、パラレルを学ぶことができるファーストフードを食べる、同時

お茶、非同期学びと学校

プロセスは知っていますか?

デザインパターンは忘れて見て、見に忘れてしまいましたか?

背景返信「デザインモード」電子ブック「デザインパターンの物語」を得ることができます

觉得文章有用帮忙转发&点赞,多谢朋友们!

リーブローター・

おすすめ

転載: juejin.im/post/5d897125e51d4557dc774f6f