1

次のコード セグメントでは、3 つのスレッドを作成し、どれがどれであるかを追跡するためにそれらに番号を付けます。プログラムを実行すると、スレッドがランダムに並べられることを除いて、出力は期待どおりです。それらが作成および開始されたのと同じ順序 (1-2-3) で表示されることを期待していましたが、毎回スクランブルされた結果が得られます。

どうしてこれなの?

PrintTaskオブジェクトはランダムな時間を作成し、スリープsleepが完了するとメッセージを出力します。コードは単純なので、投稿しません。ExecutorService別のスレッド オブジェクトの代わりにを使用すると、同じことが起こります。

public static void main(String[] args) {
    Thread thread1 = new Thread(new PrintTask("Thread 1"));
    Thread thread2 = new Thread(new PrintTask("Thread 2"));
    Thread thread3 = new Thread(new PrintTask("Thread 3"));

    System.err.println("Starting threads");

    thread1.start();
    thread2.start();
    thread3.start();

    System.err.println("Threads started, main ends\n");
}

出力:

スレッド 2 は 4907 の間スリープ状態になります

スレッド 1 は 4779 の間スリープ状態になります

スレッド 3 は 537 の間スリープ状態になります

スレッド 3 スリープ完了

スレッド 1 のスリープが完了しました

スレッド 2 スリープ完了

4

4 に答える 4

4

それらが作成されて開始されたのと同じ順序で表示されることを期待していました(1-2-3)

いいえ、スレッドの実行順序は保証されません。

于 2013-01-07T17:54:12.543 に答える
1

スレッドの実行スケジュールは、フレームワーク スケジューラ、OS スケジューラ、ハードウェアなど、多くの要因によって異なります。明示的な調整がない場合は、同時に実行されているスレッド間の操作の特定の順序に依存するべきではありません。最初の命令を開始してから実際に実行するまでの間に、スケジューラによってスレッドが CPU から切り離されることがよくあります。

于 2013-01-07T18:16:58.127 に答える
1

あなたが持っている唯一の保証はそれです(JLS 17.4.5):

スレッドでの start() の呼び出しは、開始されたスレッドのアクションの前に発生します。

ただし、複数のスレッドが関与する場合は保証されないため、目的の出力を取得するには何らかの形式の同期を使用する必要があります。

于 2013-01-07T17:55:17.920 に答える
1

それらが作成されて開始されたのと同じ順序で表示されることを期待していました(1-2-3)

そのような保証は提供されません。

于 2013-01-07T17:56:29.493 に答える