12

Javaでスレッドの優先順位がどのように機能するかを誰でも説明できますか? ここでの混乱は、JavaThreadがその優先度に従っての実装を保証しない場合、なぜこのsetpriority()関数が使用されるのかということです。

私のコードは次のとおりです。

public class ThreadSynchronization implements Runnable{

    public synchronized void run() {
        System.out.println("Starting Implementation of Thread "+Thread.currentThread().getName());
        for(int i=0;i<10;i++)
        {
            System.out.println("Thread "+Thread.currentThread().getName()+" value : "+i);
        }
        System.out.println("Ending Implementation of Thread "+Thread.currentThread().getName());
    }

    public static void main(String[] args) {
        System.out.println("Program starts...");
        ThreadSynchronization th1 = new ThreadSynchronization();
        Thread t1 = new Thread(th1);
        t1.setPriority(1);
        synchronized(t1)
        {
            t1.start();
        }

        ThreadSynchronization th2 = new ThreadSynchronization();
        Thread t2 = new Thread(th2);
        t2.setPriority(9);
        synchronized (t2) {
            t2.start(); 
        }

        System.out.println("Program ends...");
    }
}

上記のプログラムでは、優先度を変更しても出力に違いはありません。また、スレッドの優先度をどのように使用できるかをリアルタイムで適用することも非常に役立ちます。ありがとう。

4

6 に答える 6

11

スレッドの優先度は、OS タスク スケジューラへの単なるヒントであり、基盤となる OS に依存します。OS は優先度の高いスレッドにより多くのリソースを割り当てようとしますが、それを保証するものではありません。したがって、プログラムがスレッドの優先度に依存している場合、プログラムを基盤となる OS にバインドすることになりますが、これは悪いことです。

Java Concurrency in Practiceから:

スレッドの優先度を使用する誘惑は避けてください。プラットフォームへの依存度が高まり、活性の問題が発生する可能性があるためです。ほとんどの並行アプリケーションは、すべてのスレッドにデフォルトの優先度を使用できます。

于 2013-12-02T16:38:38.410 に答える
5

スレッドの優先度は、OS タスク スケジューラへのヒントにすぎません。タスク スケジューラは、優先度の高いスレッドにより多くのリソースを割り当てようとしますが、明示的な保証はありません。

実際、これは Java や JVM だけに関連するものではありません。ほとんどの非リアルタイム OS は、示唆的な方法でのみスレッドの優先度 (マネージドまたはアンマネージド) を使用します。

また、非常に重要なことですが、優先度は基盤となるプラットフォームごとに異なります。したがって、Java のプラットフォームの自由を失います。この要約も参照してください。

実際、一部の優先度レベルは、同じ「ネイティブ」優先度レベルにマップできます。リストは次のとおりです (OpenJDK 6 の Hotspot コードに基づく)。

Solaris
1 ⇒ 0
2 ⇒ 32
3 ⇒ 64
4 ⇒ 96
5 – 10 ⇒ 127
注意すべき点として、Solaris では、スレッドの優先度を通常よりも上げることができず、下げることしかできないことに注意してください。より高い値の。

Linux
1 – 10 ⇒ 4 – -5 (適切な値) 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

私は多くのマルチスレッド Java アプリケーションを開発してきましたが、私の意見では、広告の優先度を設定する必要がある場合、別の問題が発生します。多くのCPU時間を消費する悪いアルゴリズムのように.... とにかくそれに頼ることができないので、私は常にJavaスレッドプリオを変更しないことをお勧めします。(もちろん、それが理にかなっているいくつかのシナリオがあります)

于 2013-12-02T16:37:33.053 に答える
1

The size of the tasks is too small and probably will complete right after the start. Also, if you have "enough" CPU cores, each worker thread will be allocated to one core, so the result will be the same.

Try the experiment in a different context, first increase the task size (for example by looping one thousand times to one million, without print) then increase the number of threads to exceed the number of cores you have and third, create your threads first and then start all the threads (you cannot start them at once, you will still need to loop through them).

In my case, I have chosen 10 threads because I ran the code on a processor with two hyper-threaded cores, running four simultaneous threads.

My changes to your example:

public class ThreadPriority implements Runnable {

    public synchronized void run() {
        System.out.println("Starting Implementation of Thread " + Thread.currentThread().getName());
        float s = 0;
        for (int i = 0; i < 1000; i++)
            for (int k = 0; k < 1000000; k++)
                s += k;
        System.out.println("Ending Implementation of Thread " + Thread.currentThread().getName() + " " + s);
    }

    Thread t;

    public ThreadPriority(String name, int prio) {
        t = new Thread(this);
        t.setName(name);
        t.setPriority(prio);
    }

    public void start() {
        synchronized (t) {
            t.start();
        }
    }

    public static void main(String[] args) {
        System.out.println("Program starts...");
        ThreadPriority[] th = new ThreadPriority[10];
        for (int i = 0; i < th.length; i++) {
            th[i] = new ThreadPriority("T" + i, i / 2 + 1);
        }

        for (ThreadPriority tp : th)
            tp.start();

        System.out.println("Program ending, wait for all the threads to complete");
    }
}

Results are:

Program starts...
Starting Implementation of Thread T0
Starting Implementation of Thread T9
Starting Implementation of Thread T8
Starting Implementation of Thread T5
Program ending, wait for all the threads to complete
Starting Implementation of Thread T4
Starting Implementation of Thread T6
Starting Implementation of Thread T7
Starting Implementation of Thread T2
Starting Implementation of Thread T3
Starting Implementation of Thread T1
Ending Implementation of Thread T6 1.7592186E13
Ending Implementation of Thread T7 1.7592186E13
Ending Implementation of Thread T4 1.7592186E13
Ending Implementation of Thread T8 1.7592186E13
Ending Implementation of Thread T9 1.7592186E13
Ending Implementation of Thread T5 1.7592186E13
Ending Implementation of Thread T2 1.7592186E13
Ending Implementation of Thread T0 1.7592186E13
Ending Implementation of Thread T1 1.7592186E13
Ending Implementation of Thread T3 1.7592186E13

As you can see, the low number threads tend to end later, because the high number threads have higher priority. By turning the scale upside down:

    for (int i = 0; i < th.length; i++) {
        th[i] = new ThreadPriority("T" + i, 9 - i / 2 );
    }

The low number threads complete faster than the high ones. Some threads complete even before other threads are started, because they have higher priority compared to the calling program:

Program starts...
Starting Implementation of Thread T0
Starting Implementation of Thread T1
Starting Implementation of Thread T2
Starting Implementation of Thread T3
Program ending, wait for all the threads to complete
Ending Implementation of Thread T2 1.7592186E13
Ending Implementation of Thread T3 1.7592186E13
Ending Implementation of Thread T0 1.7592186E13
Ending Implementation of Thread T1 1.7592186E13
Starting Implementation of Thread T9
Starting Implementation of Thread T4
Starting Implementation of Thread T8
Starting Implementation of Thread T7
Starting Implementation of Thread T5
Starting Implementation of Thread T6
Ending Implementation of Thread T4 1.7592186E13
Ending Implementation of Thread T5 1.7592186E13
Ending Implementation of Thread T7 1.7592186E13
Ending Implementation of Thread T8 1.7592186E13
Ending Implementation of Thread T9 1.7592186E13
Ending Implementation of Thread T6 1.7592186E13
于 2016-05-11T13:12:15.557 に答える