I.はじめに
()に参加すると、定義JDKのドキュメントによると、Threadクラスのメソッドである、join()メソッドの役割は、別の呼び出しを待つために、現在のスレッドを実行しているスレッドがダウンして実行終了後にjoin()メソッドを、スレッドの終了を待つことです。スレッドの実行は、一般的に他の呼び出しメインスレッドを進める前に、メイン終了のjoin()メソッドを待って、メインメインスレッドで使用されています。
/**
* Waits for this thread to die.
*
*/
public final void join() throws InterruptedException
复制代码
II。使用例を
次の2つの例では、方法はイエスである()のは、使用が参加するどのような影響を見てみましょう。
参加使用せず1.()メソッド
public class CreateThreadTest {
public static void main(String[] args) {
System.out.println("主线程执行开始");
Thread threadA = new Thread(new RunnableTest(), "线程A");
threadA.start();
System.out.println("主线程执行结束");
}
}
class RunnableTest implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行结束");
}
}
复制代码
次のように実行結果は以下のとおりです。
主线程执行开始
线程A执行开始
主线程执行结束
线程A执行结束
复制代码
そのためこれらのサブスレッドの実行時間の比較的長いので、メインスレッドの終了後に終了するまで、サブスレッドの実行を実行します。
2.参加()メソッドの使用
public class CreateThreadTest {
public static void main(String[] args) {
System.out.println("主线程执行开始");
Thread threadA = new Thread(new RunnableTest(), "线程A");
threadA.start();
try {
threadA.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("主线程执行结束");
}
}
class RunnableTest implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "执行开始");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行结束");
}
}
复制代码
次のように実行結果は以下のとおりです。
主线程执行开始
线程A执行开始
线程A执行结束
主线程执行结束
复制代码
サブスレッドスレッドA・コールは、join()メソッドの後、私たちは、メインスレッドが実行の終わりを下に継続するために子スレッドが終了するまで待機しますことを見出しました。
原則的方法3 .join()
join()メソッドについての洞察を得るためにThreadクラスのソースコード(JDK1.8)を下記によって:
public final void join() throws InterruptedException {
join(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;
}
}
}
复制代码
上記のコードは、2つのコードのいずれかを注意してください。
public final synchronized void join(long millis) throws InterruptedException {}
复制代码
これは同期メソッドプラス命令のメンバー(これを)同期され、?これは、スレッドAの子スレッドオブジェクトそのものです。換言すれば、メインスレッドは、このサブスレッドオブジェクトスレッドAロックを保持しています。
第二:
while (isAlive()) {
wait(0);
}
复制代码
この待機()メソッドは、Objectクラスのメソッドであることに注意してください、それは彼らが再び目覚めたまで、スレッドAのオブジェクトが待機状態に入り、ロックを解除します待ち()メソッドを実行した後、メインスレッドです。我々はすべて知っているように、その意志、待機()、)(そこに通知しなければならないと、通知?のJVMソースで:
//一个c++函数:
void JavaThread::exit(bool destroy_vm, ExitType exit_type) ;
//里面有一个贼不起眼的一行代码
ensure_join(this);
static void ensure_join(JavaThread* thread) {
Handle threadObj(thread, thread->threadObj());
ObjectLocker lock(threadObj, thread);
thread->clear_pending_exception();
java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
java_lang_Thread::set_thread(threadObj(), NULL);
//同志们看到了没,别的不用看,就看这一句
//thread就是当前线程,是啥?就是刚才例子中说的threadA线程
lock.notify_all(thread);
thread->clear_pending_exception();
}
复制代码
子スレッドが実行終了をスレッドAすると、JVMはメインスレッドである我々の場合には、スレッドAスレッドオブジェクト上のブロックを自動的に起動します。これまでのところ、スレッドAスレッドオブジェクトは、また、メインスレッドがもう実行し続けることができるようになります、のnotifyAllです。
IV。まとめ
join()メソッドは、同期方式であるのでので、主にメインスレッドは、threadA.join()メソッドを呼び出してメインスレッドは、第1のロックスレッドスレッドオブジェクトを保持します。次の呼び出しは、()メソッドを待つ()メソッドへの参加、メインスレッドは、待機状態に、ロック・スレッドスレッドオブジェクトを解放します。最後に、スレッドAスレッドの実行が終了すると、JVM呼び出し(スレッド)lock.notify_all;ウェイクスレッドAは、オブジェクトのロック・スレッドがメインスレッドで保持しているメインスレッドは実装をダウンしていきます。
参考: