まず、実行スレッドの順序は不明です
スレッドを開始するときに、実行順序のスレッドが不確実であるスレッドのstart()メソッドを呼び出します。連続的に複数のスレッドを作成した後、他の言葉で、同じ方法で、スレッドは、実行スレッドの順序を決定しないためのstart()メソッドを呼び出します。
例えば、ここでは、以下のように、簡単な例を考えてみましょう。
package io.binghe.concurrent.lab03;
/**
* @author binghe
* @version 1.0.0
* @description 线程的顺序,直接调用Thread.start()方法执行不能确保线程的执行顺序
*/
public class ThreadSort01 {
public static void main(String[] args){
Thread thread1 = new Thread(() -> {
System.out.println("thread1");
});
Thread thread2 = new Thread(() -> {
System.out.println("thread2");
});
Thread thread3 = new Thread(() -> {
System.out.println("thread3");
});
thread1.start();
thread2.start();
thread3.start();
}
}
ThreadSort01クラスでは、我々は、3つの異なるスレッド、スレッド1、スレッド2とthread3、次のプログラムのコールthread1.startに順に()はそれぞれ、thread2.start()とそれぞれ開始するthread3.start()メソッドを作成しました。三つの異なるスレッド。
だから、質問は実行スレッドの順序の順にスレッド1、スレッド2とthread3でそれを実行するかどうか、ですか?メインThreadSort01結果の操作方法を以下に示します。
thread1
thread2
thread3
もう一度実行して、結果を以下に示します。
thread1
thread3
thread2
第三の実行、結果を以下に示します。
thread2
thread3
thread1
これは、プログラムが実行されるたびに見ることができ、実行スレッドの順序が異なる場合があります。スレッドの起動シーケンスは実行スレッドの順序を決定するものではありません。
第二に、どのように注文スレッドの実施を確保するために
1.スレッドの実行順序の簡単な例を確認してください
実際のビジネス・シナリオでは、時々、スレッドを開始した後は、まず依存しているスレッドが適切な実行スレッドを完了するために、ビジネスロジックを実行開始する必要があるかもしれません。この時点で、実行スレッドの順番を確保する必要があります。それでは、どのように実行スレッドの順序それことを保証するのですか?
あなたは、実行スレッドの順序を保証するために、Threadクラスの()メソッドに参加することができます。例えば、次のテストコード。
package io.binghe.concurrent.lab03;
/**
* @author binghe
* @version 1.0.0
* @description 线程的顺序,Thread.join()方法能够确保线程的执行顺序
*/
public class ThreadSort02 {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println("thread1");
});
Thread thread2 = new Thread(() -> {
System.out.println("thread2");
});
Thread thread3 = new Thread(() -> {
System.out.println("thread3");
});
thread1.start();
//实际上让主线程等待子线程执行完成
thread1.join();
thread2.start();
thread2.join();
thread3.start();
thread3.join();
}
}
我々は、各スレッドのstartメソッドは、スレッド()メソッドに参加するには、次の呼び出しを追加し、ThreadSort02類推ThreadSort01クラスを参照してくださいすることができます。この場合、操作ThreadSort02クラス結果を以下に示します。
thread1
thread2
thread3
もう一度実行して、結果を以下に示します。
thread1
thread2
thread3
第三の実行、結果を以下に示します。
thread1
thread2
thread3
あなたが見ることができ、各実行結果は同じなので、スレッドを使用すると、スレッドが順番に実行していることを確実にするために()メソッドに参加します。
どのように2.join実行スレッドの順序を保証する方法
以来実行スレッドの順という、我々は最終的には参加Threadクラス()メソッドを見てみましょう確保するためのThreadクラスのjoin()メソッドは、どのような幽霊です。
以下に示すように、スレッドは、join()メソッドを入力します。
public final void join() throws InterruptedException {
join(0);
}
パラメーター0を渡し、()メソッドを結合類似の参照に参加()メソッドの呼び出しを参照。コードをフォローアップするには、次の通り。
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
あなたが長い参加型パラメータがあり、見ることができる()メソッドの使用は、この方法が唯一の時間またはメソッド呼び出しに一つのインスタンスであることを示す、修飾synchroinzed。ので、0に渡すパラメータ、プログラムは次のコードのロジックを入力します。
if (millis == 0) {
while (isAlive()) {
wait(0);
}
}
まず、既にアクティブ状態で開始した場合、現在のスレッドは、アクティブ状態で開始されたかどうかを決定するwhileループコード方法は、待機()メソッドは、そのようなものを呼び出し、およびパラメータ0を渡しています。示さ待機として、()メソッドをフォローアップ。
public final native void wait(long timeout) throws InterruptedException;
あなたは、待機()メソッドは、完全に実行するためのスレッドを待機させるための基礎となるJDK JNIの方法と手段を呼び出すことで、地元の方法で、見ることができます。
なお、呼び出し元のスレッド待機()メソッドは、再度実行ダウンが完了した後に実行され、子スレッドを待って、待ち状態でメインスレッドを行います。その実行は、メインThreadSort02クラス()メソッドでは、子スレッドを呼び出してjoin()メソッドは、main()メソッド、子スレッドの実行が完了すると、main()メソッドがダウンしていきます、開始をブロックします第2のサブスレッド、およびビジネスロジックサブスレッドを実行し、上のように。