zoukankan      html  css  js  c++  java
  • JAVA join()方法

    转自:http://www.open-open.com/lib/view/open1371741636171.html

    一、为什么要用join()方法

    在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算,主线程往往将于子线程之前结束,但是如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到join()方法了。

    二、join方法的作用

    在JDk的API里对于join()方法是:

    join

    public final void join() throws InterruptedException Waits for this thread to die. Throws: InterruptedException  - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.

    即join()的作用是:“等待该线程终止”,这里需要理解的就是该线程是指的主线程等待子线程的终止。也就是在子线程调用了join()方法后面的代码,只有等到子线程结束了才能执行。

    三、使用方式。

    join是Thread类的一个方法,启动线程后直接调用,例如:

    Thread t = new AThread(); t.start(); t.join();

    四、用实例来理解

    写一个简单的例子来看一下join()的用法:

    1.AThread 类

    1. BThread类

    2. TestDemo 类

      class BThread extends Thread {
          public BThread() {
              super("[BThread] Thread");
          };
          public void run() {
              String threadName = Thread.currentThread().getName();
              System.out.println(threadName + " start.");
              try {
                  for (int i = 0; i < 5; i++) {
                      System.out.println(threadName + " loop at " + i);
                      Thread.sleep(1000);
                  }
                  System.out.println(threadName + " end.");
              } catch (Exception e) {
                  System.out.println("Exception from " + threadName + ".run");
              }
          }
      }
      class AThread extends Thread {
          BThread bt;
          public AThread(BThread bt) {
              super("[AThread] Thread");
              this.bt = bt;
          }
          public void run() {
              String threadName = Thread.currentThread().getName();
              System.out.println(threadName + " start.");
              try {
                  bt.join();
                  System.out.println(threadName + " end.");
              } catch (Exception e) {
                  System.out.println("Exception from " + threadName + ".run");
              }
          }
      }
      public class TestDemo {
          public static void main(String[] args) {
              String threadName = Thread.currentThread().getName();
              System.out.println(threadName + " start.");
              BThread bt = new BThread();
              AThread at = new AThread(bt);
              try {
                  bt.start();
                  Thread.sleep(2000);
                  at.start();
                  at.join();
              } catch (Exception e) {
                  System.out.println("Exception from main");
              }
              System.out.println(threadName + " end!");
          }
      }
      

        

      打印结果:

      main start.    //主线程起动,因为调用了at.join(),要等到at结束了,此线程才能向下执行。 
      [BThread] Thread start. 
      [BThread] Thread loop at 0 
      [BThread] Thread loop at 1 
      [AThread] Thread start.    //线程at启动,因为调用bt.join(),等到bt结束了才向下执行。 
      [BThread] Thread loop at 2 
      [BThread] Thread loop at 3 
      [BThread] Thread loop at 4 
      [BThread] Thread end. 
      [AThread] Thread end.    // 线程AThread在bt.join();阻塞处起动,向下继续执行的结果 
      main end!      //线程AThread结束,此线程在at.join();阻塞处起动,向下继续执行的结果。
      修改一下代码:
       1 public class TestDemo {
       2     public static void main(String[] args) {
       3         String threadName = Thread.currentThread().getName();
       4         System.out.println(threadName + " start.");
       5         BThread bt = new BThread();
       6         AThread at = new AThread(bt);
       7         try {
       8             bt.start();
       9             Thread.sleep(2000);
      10             at.start();
      11             //at.join(); //在此处注释掉对join()的调用
      12         } catch (Exception e) {
      13             System.out.println("Exception from main");
      14         }
      15         System.out.println(threadName + " end!");
      16     }
      17 }

      打印结果:

      main start.    // 主线程起动,因为Thread.sleep(2000),主线程没有马上结束;
      
      [BThread] Thread start.    //线程BThread起动
      [BThread] Thread loop at 0
      [BThread] Thread loop at 1
      main end!   // 在sleep两秒后主线程结束,AThread执行的bt.join();并不会影响到主线程。
      [AThread] Thread start.    //线程at起动,因为调用了bt.join(),等到bt结束了,此线程才向下执行。
      [BThread] Thread loop at 2
      [BThread] Thread loop at 3
      [BThread] Thread loop at 4
      [BThread] Thread end.    //线程BThread结束了
      [AThread] Thread end.    // 线程AThread在bt.join();阻塞处起动,向下继续执行的结果

      五、从源码看join()方法

      在AThread的run方法里,执行了bt.join();,进入看一下它的JDK源码:

      public final void join() throws InterruptedException {
          join(0L);
      }
      然后进入join(0L)方法:
      public final synchronized void join(long l)
          throws InterruptedException
      {
          long l1 = System.currentTimeMillis();
          long l2 = 0L;
          if(l < 0L)
              throw new IllegalArgumentException("timeout value is negative");
          if(l == 0L)
              for(; isAlive(); wait(0L));
          else
              do
              {
                  if(!isAlive())
                      break;
                  long l3 = l - l2;
                  if(l3 <= 0L)
                      break;
                  wait(l3);
                  l2 = System.currentTimeMillis() - l1;
              } while(true);
      }
  • 相关阅读:
    ES6 | 关于class类 继承总结
    ES6 | class类的基本语法总结
    开发辅助 | 阿里图标库iconfont入门使用
    JS基本功 | JavaScript专题之数组 方法总结
    前端模块化 | 解读JS模块化开发中的 require、import 和 export
    IOS开发中UITableView和UITableViewCell的几种样式
    SSM项目的搭建
    Linux离线安装Docker
    Http项目转Https项目
    SpringBoot项目的搭建
  • 原文地址:https://www.cnblogs.com/centor/p/5976134.html
Copyright © 2011-2022 走看看