Thread.join()的使用
代码清单:
- package com.baidu.nuomi.concurrent;
- import java.util.concurrent.TimeUnit;
- /**
- * Created by sonofelice on 16/6/18.
- */
- public class Join {
- public static void main(String[] args) throws Exception{
- Thread previous = Thread.currentThread();
- for (int i = 0; i < 10; i++) {
- Thread thread = new Thread(new Domino(previous),String.valueOf(i));
- thread.start();
- previous = thread;
- }
- TimeUnit.SECONDS.sleep(5);
- System.out.println(Thread.currentThread().getName() + " terminate.");
- }
- static class Domino implements Runnable{
- private Thread thread;
- public Domino(Thread thread){
- this.thread = thread;
- }
- @Override
- public void run() {
- try {
- thread.join();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + " terminate. ");
- }
- }
- }
输出结果如下:
- main terminate.
- 0 terminate.
- 1 terminate.
- 2 terminate.
- 3 terminate.
- 4 terminate.
- 5 terminate.
- 6 terminate.
- 7 terminate.
- 8 terminate.
- 9 terminate.
- Process finished with exit code 0
从上述输出可以看到,每个线程终止的前提是前驱线程的终止,每个线程等待前驱线程终止后,才从join方法返回。
代码中创建了10个线程,0~9,每个线程调用前一个线程的join方法,也就是线程0结束了,线程1才能从join方法中返回,而线程0需要等待main线程结束。
看一下join方法的源码:
- /**
- * Waits at most {@code millis} milliseconds for this thread to
- * die. A timeout of {@code 0} means to wait forever.
- *
- * <p> This implementation uses a loop of {@code this.wait} calls
- * conditioned on {@code this.isAlive}. As a thread terminates the
- * {@code this.notifyAll} method is invoked. It is recommended that
- * applications not use {@code wait}, {@code notify}, or
- * {@code notifyAll} on {@code Thread} instances.
- *
- * @param millis
- * the time to wait in milliseconds
- *
- * @throws IllegalArgumentException
- * if the value of {@code millis} is negative
- *
- * @throws InterruptedException
- * if any thread has interrupted the current thread. The
- * <i>interrupted status</i> of the current thread is
- * cleared when this exception is thrown.
- */
- 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;
- }
- }
- }
我们调用的join方法没有传参数,就是漂黄的那一段代码,默认millis=0的。
当线程终止时,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程。加锁、循环、处理逻辑。跟上一篇博文中的等待/通知经典范式一致。