- カウントダウンタイマーCountDownLatchによって実現されます。
CountDownLatch は、カウンターを介してより柔軟な制御を提供し、カウンターが 0 であることが検出される限り、対応するスレッドが実行されているかどうかに関係なく、現在のスレッドを実行できます。
private static CountDownLatch countDownLatch2 = new CountDownLatch(1);
private static CountDownLatch countDownLatch3 = new CountDownLatch(1);
@Test
public void test1() throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
countDownLatch2.countDown();
}, "线程1");
Thread thread2 = new Thread(() -> {
try {
countDownLatch2.await();
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
countDownLatch3.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程2");
Thread thread3 = new Thread(() -> {
try {
countDownLatch3.await();
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程3");
thread3.start();
thread2.start();
thread1.start();
}
- メインスレッドでは、順序は join() メソッドによって指定され、
現在のスレッドは join() メソッドによって「ブロック」され、指定されたスレッドの実行が終了した後も実行が続行されます。
スレッド thread2 に thread1.join() を追加します。これは、現在のスレッド 2 がこのコード行まで実行されるとブロック状態になり、スレッド thread1 が実行されるまでスレッド thread2 は実行を継続しないことを意味します。これにより、スレッド thread1 とスレッド thread2 の実行順序が保証されます。
最下位層はjdk synchronized wait Noticeによって実現されます
@Test
public void test2() throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
}, "线程1");
Thread thread2 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
}, "线程2");
Thread thread3 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
}, "线程3");
thread1.start();
thread1.join();
thread2.start();
thread2.join();
thread3.start();
}
- 子スレッドの join() メソッドで順序を指定します。
@Test
public void test3() throws InterruptedException {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
}, "线程1");
Thread thread2 = new Thread(() -> {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
}, "线程2");
Thread thread3 = new Thread(() -> {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
}, "线程3");
thread3.start();
thread2.start();
thread1.start();
}
- シングルスレッドプール newSingleThreadExecutor() を作成することで実現
static ExecutorService executorService = Executors.newSingleThreadExecutor();
@Test
public void test4() {
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "打开冰箱");
});
Thread thread2 = new Thread(() -> {
try {
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "拿出可乐" );
});
Thread thread3 = new Thread(() -> {
try {
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "关上冰箱" );
});
executorService.submit(thread1);
executorService.submit(thread2);
executorService.submit(thread3);
executorService.shutdown();
}