JDK 是这样说的:join public final void join (long millis )throws InterruptedException Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
thread1.join(10000)表示主线程将等待thread1运行10000后,才开始继续运行该语句后面的语句。
public static void main(String args[]){
Thread t1= new Thread(new Runnable() {
@Override
public void run() {
int i=10000000;
while(i>0){
System.out.println("run():"+i);
i--;
}
}
});
t1.setDaemon(true);
t1.start();
try {
t1.join(10000);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
while(true){
System.out.println("main():"+Thread.currentThread().getName());
}
}
可以看出主线程一直在等待t1线程的运行,等了10000后,主线程的while语句开始执行,由于此时t1线程也未结束,故main线程与t1线程交替执行。故join的意思就是,主线程等待子线程若干秒后一起参与进来。
当join(0)时表示主线程将一直等待t1线程执行结束后才开始执行。
public static void main(String args[]){
Thread t1= new Thread(new Runnable() {
@Override
public void run() {
int i=1000000;
while(i>0){
System.out.println("run():"+i);
i--;
}
}
});
t1.setDaemon(true);
t1.start();
try {
t1.join(0);
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
while(true){
System.out.println("main():"+Thread.currentThread().getName());
}
}
可以看到t1完成以后,main线程开始执行。
源码:
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;
}
}
}
首先, 当main 线程调用t.join 时候,main 线程会获得线程对象t1 的锁 , 判断t1对象所对应的线程是否活动状态,若为活动状态,那么就调用该对象的wait( 等待时间) ,也就是说main线程进入了t1对象的等待池。
now变量是一个记录从触发该方法到当前时间的累积。delay表示还需等待多久,如果t1线程一直存活着,那么delay将被不断的计算,并且将不断地设置main线程等待的时间,假设某时循环到delay=1,此时设置main等待1,在下一次计算时delay可能等于-2,那么此时程序将跳出join方法,而main线程等待1之后将执行后面的语句。