代码清单:

  1. package com.baidu.nuomi.concurrent;
  2. import java.util.concurrent.TimeUnit;
  3. /**
  4. * Created by sonofelice on 16/6/18.
  5. */
  6. public class Join {
  7. public static void main(String[] args) throws Exception{
  8. Thread previous = Thread.currentThread();
  9. for (int i = 0; i < 10; i++) {
  10. Thread thread = new Thread(new Domino(previous),String.valueOf(i));
  11. thread.start();
  12. previous = thread;
  13. }
  14. TimeUnit.SECONDS.sleep(5);
  15. System.out.println(Thread.currentThread().getName() + " terminate.");
  16. }
  17. static class Domino implements Runnable{
  18. private Thread thread;
  19. public Domino(Thread thread){
  20. this.thread = thread;
  21. }
  22. @Override
  23. public void run() {
  24. try {
  25. thread.join();
  26. } catch (InterruptedException e) {
  27. e.printStackTrace();
  28. }
  29. System.out.println(Thread.currentThread().getName() + " terminate. ");
  30. }
  31. }
  32. }

输出结果如下:

  1. main terminate.
  2. 0 terminate.
  3. 1 terminate.
  4. 2 terminate.
  5. 3 terminate.
  6. 4 terminate.
  7. 5 terminate.
  8. 6 terminate.
  9. 7 terminate.
  10. 8 terminate.
  11. 9 terminate.
  12. Process finished with exit code 0

从上述输出可以看到,每个线程终止的前提是前驱线程的终止,每个线程等待前驱线程终止后,才从join方法返回。

代码中创建了10个线程,0~9,每个线程调用前一个线程的join方法,也就是线程0结束了,线程1才能从join方法中返回,而线程0需要等待main线程结束。

看一下join方法的源码:

  1. /**
  2. * Waits at most {@code millis} milliseconds for this thread to
  3. * die. A timeout of {@code 0} means to wait forever.
  4. *
  5. * <p> This implementation uses a loop of {@code this.wait} calls
  6. * conditioned on {@code this.isAlive}. As a thread terminates the
  7. * {@code this.notifyAll} method is invoked. It is recommended that
  8. * applications not use {@code wait}, {@code notify}, or
  9. * {@code notifyAll} on {@code Thread} instances.
  10. *
  11. * @param millis
  12. * the time to wait in milliseconds
  13. *
  14. * @throws IllegalArgumentException
  15. * if the value of {@code millis} is negative
  16. *
  17. * @throws InterruptedException
  18. * if any thread has interrupted the current thread. The
  19. * <i>interrupted status</i> of the current thread is
  20. * cleared when this exception is thrown.
  21. */
  22. public final synchronized void join(long millis)
  23. throws InterruptedException {
  24. long base = System.currentTimeMillis();
  25. long now = 0;
  26. if (millis < 0) {
  27. throw new IllegalArgumentException("timeout value is negative");
  28. }
  29. if (millis == 0) {
  30. while (isAlive()) {
  31. wait(0);
  32. }
  33. } else {
  34. while (isAlive()) {
  35. long delay = millis - now;
  36. if (delay <= 0) {
  37. break;
  38. }
  39. wait(delay);
  40. now = System.currentTimeMillis() - base;
  41. }
  42. }
  43. }

我们调用的join方法没有传参数,就是漂黄的那一段代码,默认millis=0的。

当线程终止时,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程。加锁、循环、处理逻辑。跟上一篇博文中的等待/通知经典范式一致。

 

版权声明:本文为sonofelice原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/sonofelice/p/5596268.html