? ? join是线程的一个方法,在API中,它的英文解释是Waits for this thread to die.等待此线程死亡。谁等待此线程死亡呢?不难看出,这过程中至少存在两个线程,一个调用线程的线程,一个被调用的线程。我们通过一个简单的示例来理解这句话。? ??
package com.doufu.thread.t01;
class ThreadA extends Thread{
private String name;
public ThreadA(String name){
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000);//让此线程等待1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name);
}
}
public class JoinTest01 {
public static void main(String[] args) throws InterruptedException {
ThreadA t = new ThreadA("T1");
t.start();
t.join();
System.out.println("main");
}
}
? ? ?在上面代码中,调用线程的线程是main即主线程,被调用的线程是t。t.join()的意思即等待t的死亡(运行结束),等待t运行结束的线程就是main。所以上面的代码执行结果应该是先打印T1,再打印main。? ??

? ? 通过以上代码,可以理解,在A线程中调用另外一个线程B的join方法,即让线程A进入Block状态,直到线程B运行结束。下面再看一个示例:
? ? ?只贴出了修改的部分
public class JoinTest01 {
public static void main(String[] args) throws InterruptedException {
ThreadA t = new ThreadA("T1");
t.join();
t.start();
System.out.println("main");
}
}
? ?运行结果:
?
? ??
? 看这输出结果,是不是觉得不对,不是好说了,在main中调用t的join方法,会让main先挂起,直到t执行结束吗,怎么先打印main了呢?我们来看下Thread类的join源码:
? ??
public final void join() throws InterruptedException {
join(0);
}
? ? join(),实际上是调用另外一个join(long millis)的方法,我们再来看下join(long millis)方法? ?
?
?
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()方法时,线程不是活着的,则无效。以下是isAlive()的源码,注意看下方法注释??
?
?
/**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.
*
* @return <code>true</code> if this thread is alive;
* <code>false</code> otherwise.
*/
public final native boolean isAlive();
? ?我们来看一个面试题:? ? ?
? ? 此面试题,我们可以用join来实现? ?
class ThreadA extends Thread{
private String name;
public ThreadA(String name){
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000);//让此线程等待1秒
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name);
}
}
class ThreadB extends Thread{
private String name;
private Thread thread;
public ThreadB(String name,Thread thread){
this.name = name;
this.thread = thread;
}
@Override
public void run() {
try {
thread.join();//让此线程进入Block
Thread.sleep(1000);//让此线程等待1秒
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.out.println(name);
}
}
public class JoinTest01 {
public static void main(String[] args) throws InterruptedException {
ThreadA t1 = new ThreadA("T1");
ThreadB t2 = new ThreadB("T2",t1);
ThreadB t3 = new ThreadB("T3",t2);
t1.start();
t2.start();
t3.start();
}
}
?运行结果:? ?

?
?
?
原文:http://h140465.iteye.com/blog/2264768