转自: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();阻塞处起动,向下继续执行的结果。

    修改一下代码:

     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(); //在此处注释掉对join()的调用
    } catch (Exception e) {
    System.out.println("Exception from main");
    }
    System.out.println(threadName + " end!");
    }
    }

    打印结果:

    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);
    }

JAVA join()方法的更多相关文章

  1. java join 方法的使用

    在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束.这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据 ...

  2. 【多线程】java多线程 测试例子 详解wait() sleep() notify() start() join()方法 等

    java实现多线程,有两种方法: 1>实现多线程,继承Thread,资源不能共享 2>实现多线程  实现Runnable接口,可以实现资源共享 *wait()方法 在哪个线程中调用 则当前 ...

  3. Java线程中yield与join方法的区别

    长期以来,多线程问题颇为受到面试官的青睐.虽然我个人认为我们当中很少有人能真正获得机会开发复杂的多线程应用(在过去的七年中,我得到了一个机会),但是理解多线程对增加你的信心很有用.之前,我讨论了一个w ...

  4. 简谈Java的join()方法

    join()是Thread类的一个方法.根据jdk文档的定义: public final void join()throws InterruptedException: Waits for this ...

  5. Java多线程中的join()方法

    一.join()方法介绍 join() 定义在Thread.java中.join()方法把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程.比如在线程B中调用了线程A的join( ...

  6. java多线程 join方法以及优先级方法

    /*join:当A线程执行到了B线程的.join()方法时,A就会等待.等B线程都执行完,A才会执行. join可以用来临时加入线程执行. 1.线程使用join方法,主线程就停下,等它执行完,那么如果 ...

  7. Java中join()方法的理解

    thread.Join把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行的线程. 比如在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B. t.join ...

  8. Java并发编程--多线程中的join方法详解

    Java Thread中, join()方法主要是让调用该方法的thread在完成run方法里面的部分后, 再执行join()方法后面的代码 例如:定义一个People类,run方法是输出姓名年龄. ...

  9. 模拟做饭系统(java+线程中的join方法)

    (一)项目框架分析 妈妈要去做饭,发现没有酱油,让儿子去买酱油,然后回来做饭. 根据面向对象的思想,有两个对象,妈妈和儿子 主要有两个方法: (一)没有线程控制(即儿子没有买酱油回来妈妈就做好饭了)+ ...

随机推荐

  1. 高性能Server---Reactor模型

    原文地址:http://www.ivaneye.com/2016/07/23/iomodel.html 无处不在的C/S架构 在这个充斥着云的时代,我们使用的软件可以说99%都是C/S架构的! 你发邮 ...

  2. [skill] 进程 线程

    在业务逻辑上: 进程线程没有区别. 在系统资源上: 进程拥有自己的地址空间.线程拥有自己的堆栈和临时变量,与其他线程共享地址空间. 在通信代价上: 线程间通信代价更低,实现更方便.进程通信相对开销比较 ...

  3. Week 1:2015/4/27~2015/5/3

    Update everyday.(Last edit:4/30 01:00) Task 1:TPO X 2.5(finish 1,then finish 2 more) Task 2:TC Tarja ...

  4. andriod逆向实验截图

  5. ife任务刷题总结(一)-css reset与清除浮动

    本文同时发布于本人的个人网站www.yaoxiaowen.com 百度创办的前端技术学院,是一个面向大学生的前端技术学习平台.虽然只有大学生才有资格报名,提交代码进行比赛排名.但是这并不妨碍我们这些初 ...

  6. java中的访问修饰符

    Java有四种访问权限,其中三种有访问权限修饰符,分别为private,public和protected,还有一种不带任何修饰符.其中package代表缺省的访问权限,具体到代码中就是不写任何修饰符的 ...

  7. VC 6中配置OpenGL开发环境

    2010,2012中配置类似 http://hi.baidu.com/yanzi52351/item/f9a600dffa4caa4ddcf9be1d VC 6中配置OpenGL开发环境 这里,我习惯 ...

  8. Linux基本操作命令

    Linux基本操作命令 首先介绍一个名词“控制台(console)”,它就是我们通常见到的使用字符操作界面的人机接口,例如dos.我们说控制台命令,就是指通过字符界面输入的可以操作系统的命令,例如do ...

  9. rbd cache (一)

    cache 1.why The existence of cache is based on a mismatch between the performance characteristics of ...

  10. cursor or set-based

    标题可能和正文不太相符.我主要是记录工作中遇到使用游标的语句改成普通set-based operation,执行时间快了很多. 1.游标语句 declare @startDate dateTime d ...