java join方法
t.join()方法阻塞调用此方法的线程(calling thread)进入 TIMED_WAITING 状态,直到线程t完成,此线程再继续
如在main线程调用t.join(),则会阻塞main线程直到t线程执行完。
而join()函数参数,当调用为t.join(2000),代表阻塞2000毫秒, 当2000毫秒完后,main线程会向下执行,
但也有例外,join(millis)
如在t线程使用 synchronized时,则必须等到synchronized包裹的代码块执行完并传递的millis毫秒后,t.join()的调用线程才会向下执行。
1 | public class Test { |
输出结果:
main线程结束
1005
休眠0
休眠1
休眠2
休眠3
休眠4
线程结束
将thread.join(1000) 改为2000 时,输出结果如下:
休眠0
main线程结束
2005
休眠1
休眠2
休眠3
休眠4
线程结束
将上面代码synchronized 注释放开后再运行,输出结果如下:
休眠0
休眠1
休眠2
休眠3
休眠4
线程结束
main线程结束
5011
查看join方法源码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31/**
* Waits at most <code>millis</code> milliseconds for this thread to
* die. A timeout of <code>0</code> means to wait forever. 当为0时,会一直阻塞调用join函数的线程,直到调用join函数的对象线程执行完毕
*/
public final synchronized void join(long millis) throws InterruptedException {
// 获取当时系统时间
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
// 当传过来的入参时间小于0,抛出异常
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
// 当等于0时,只要线程未执行完毕,则一直阻塞
while (isAlive()) {
// 当前线程未执行完一直阻塞
wait(0);
}
} else {
// 当时间大于0
while (isAlive()) {
// 当前线程还未执行完,则一直循环获取时间,阻塞调用线程到时间结束
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
注意:
wait()是运行在调用线程的,
如在main线程中调用t.join();
则join()函数的调用线程是main线程,wait()也是运行在main线程的,所以阻塞main线程,
而t才是join()的调用对象线程,isAlive也是判断的t线程是否执行完毕,只有在t线程执行完毕,isAlive才为false