一、使用方式。

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

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

二、为什么要用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()方法后面的代码,只有等到子线程结束了才能执行

四、用实例来理解

package com.tonyluis;
class BThread extends Thread {
public BThread() {
super("Thread B");//threadName
};
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);//1000ms执行一次,便于计时
}
System.out.println(threadName + " end");
} catch (Exception e) {
System.out.println("Exception from " + threadName);
}
}
}
class AThread extends Thread {
BThread bt;
public AThread(BThread bt) {
super("Thread A");
this.bt = bt;
}
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start");
try {
bt.join();//先执行bt线程
System.out.println(threadName + " end");
} catch (Exception e) {
System.out.println("Exception from " + threadName);
}
}
}
public class TestThreadJoin {
public static void main(String[] args) {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " start");//main Thread
BThread bt = new BThread();
AThread at = new AThread(bt);
try {
bt.start();
Thread.sleep(2000);//主线程休息,正好执行两个Loop
at.start();
at.join();//让主线程等待at线程,否则主线程直接往下执行了
} catch (Exception e) {
System.out.println("Exception from main");
}
System.out.println(threadName + " end!");
}
}

运行结果:

main start
Thread B start
Thread B loop at 0
Thread B loop at 1
Thread B loop at 2//可能执行两个Loop也可能3个Loop
Thread A start
Thread B loop at 3
Thread B loop at 4
Thread B loop at 5
Thread B end
Thread A end
main end!

五、从源码看join()方法

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

public final void join() throws InterruptedException {
join(0L);//后面参数为wait的最大时间,如果是0表示永远等待直到该线程执行完毕
}

然后进入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);
}

单纯从代码上看:

如果线程被生成了,但还未被起动,isAlive()将返回false,调用它的join()方法是没有作用的。将直接继续向下执行。

在AThread类中的run方法中,bt.join()是判断bt的active状态,如果bt的isActive()方法返回false,在 bt.join(),这一点就不用阻塞了,可以继续向下进行了。从源码里看,wait方法中有参数,也就是不用唤醒谁,只是不再执行wait,向下继续执 行而已。

在join()方法中,对于isAlive()和wait()方法的作用对象是个比较让人困惑的问题:

isAlive()方法的签名是:public final native boolean isAlive(),也就是说isAlive()是判断当前线程的状态,也就是bt的状态。

wait()方法在jdk文档中的解释如下:

Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).

The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

在这里,当前线程指的是at。

Java Thread.join()方法的更多相关文章

  1. JAVA THREAD.JOIN方法详解

    一.使用方式. join是Thread类的一个方法,启动线程后直接调用,例如: Thread t = new AThread(); t.start(); t.join(); 二.为什么要用join() ...

  2. [译]Java Thread join示例与详解

    Java Thread join示例与详解 Java Thread join方法用来暂停当前线程直到join操作上的线程结束.java中有三个重载的join方法: public final void ...

  3. Java Thread.join的作用和原理

    很多人对Thread.join的作用以及实现了解得很少,毕竟这个api我们很少使用.这篇文章仍然会结合使用及原理进行深度分析 内容导航 Thread.join的作用 Thread.join的实现原理 ...

  4. Java java.lang.Thread#join()方法分析

    结论:A 线程调用 B 线程对象的 join 方法,则 A 线程会被阻塞,直到 B 线程 挂掉 (Java Doc 原话: Watis for this thread to die). 一.分析 查看 ...

  5. Java Thread join() 的用法

    Java Thread中, join() 方法主要是让调用改方法的thread完成run方法里面的东西后, 在执行join()方法后面的代码.示例: class ThreadTesterA imple ...

  6. 简谈Java的join()方法

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

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

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

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

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

  9. Java通过join方法来暂停当前线程

    目标线程的join方法暂停当前线程,直到目前线程完成(从run()方法返回). Java代码: package Threads; import java.io.IOException; /** * C ...

随机推荐

  1. SQLSERVER2008R2正确使用索引

    T1表 10000000万条数据,(插入时间36分钟,count(*)查询19秒,空间占用670M左右) 1.真正充分的利用索引比如like '张%' 就是符合SARG(符合扫描参数)标准而like ...

  2. thinkphp- 许愿墙-1

    控制器的方法, 要显示的模板默认的跟方法名相同. 也可以不同, 但应该 仍然是对应文件夹下的html模板文件: $this->display('其他的模板html文件名, 不用加html扩展名' ...

  3. Java实现zip压缩多个文件下载

    为了更好的演示,首先创建一个文件实体FileBean,包含了文件路径和文件名称: package com.javaweb.entity; import java.io.Serializable; /* ...

  4. solr多条件查询(三)

    1.昨天记了一下三条件的“并且” “并且”(  &&   &&  )的情况,今天再来记一下 “并且”  “或者” 的情况. 这里的或者情况,一定要搞清楚无论有多少情况, ...

  5. Excel 单元格自定义格式技巧总结

    第一部分 Excel 中的单元格格式是一个最基本但是又很高级的技能,说它基本是因为我们几乎天天都会用到它,会用它来设置一些简单的格式,比如日期,文本等等:高级是因为利用 Excel 单元格的自定义格式 ...

  6. R笔记 map_leaflet googlevis

    packages : map leaflet library(leaflet) library(maps) mapStates = map("state", fill = TRUE ...

  7. 调用WebService 实现在线双向翻译

    >先了解一下Web Service的基本概念: Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传 ...

  8. POJ 2452 Sticks Problem

    RMQ+二分....枚举 i  ,找比 i 小的第一个元素,再找之间的第一个最大元素.....                   Sticks Problem Time Limit: 6000MS ...

  9. MySql的count统计结果

    起因:最近在学习mysql的数据库,发现在innodb表中大数据量下count(*)的统计结果实在是太慢,所以想找个办法替代这种查询,下面分享一下我查找的过程. 实践:在给出具体的结论之前,我们先看看 ...

  10. mysql索引优化

    mysql 索引优化 >mysql一次查询只能使用一个索引.如果要对多个字段使用索引,建立复合索引. >越小的数据类型通常更好:越小的数据类型通常在磁盘.内存和CPU缓存中都需要更少的空间 ...