Join方法
作用:主线程进入阻塞状态,让“主线程”等待“子线程”结束之后才能继续运行。
注意: 是调用join()方法的当前线程进入阻塞,而不是被调用的线程对象进入阻塞。
join()是相对当前线程的,如果在当前线程调用了两个线程的join()方法,比如在main线程中先调用t1.join(),然后调用t2.join();这样只能保证t1和t2线程在主线程结束前执行完,并不会决定t1和t2在主线程中的执行顺序。
也可以在线程自己的执行体中调用自己的join()方法,这样会导致该线程永远不可能结束。
Thread.currentThread().join();
join()方法必须放到start()方法之后
三个重载的方法:
后两个需要传给join()方法一个时间,表示如果被调用的线程在规定的时间没有执行完,主线程将不再等待。
例子:不用join()方法
public static void main(String[] args) {
Thread t1=new Thread(()->{
IntStream.range(1,10)
.forEach(i->System.out.println(Thread.currentThread().getName()+"->"+i));
});
t1.start();
IntStream.range(1,10)
.forEach(i->System.out.println(Thread.currentThread().getName()+"->"+i));
}
执行结果:
Thread-0->1
Thread-0->2
Thread-0->3
main->1
main->2
main->3
main->4
main->5
main->6
main->7
main->8
main->9
Thread-0->4
Thread-0->5
Thread-0->6
Thread-0->7
Thread-0->8
Thread-0->9
添加join()方法:
public static void main(String[] args) {
Thread t1=new Thread(()->{
IntStream.range(1,10)
.forEach(i->System.out.println(Thread.currentThread().getName()+"->"+i));
});
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
IntStream.range(1,10)
.forEach(i->System.out.println(Thread.currentThread().getName()+"->"+i));
}
执行结果:
Thread-0->1
Thread-0->2
Thread-0->3
Thread-0->4
Thread-0->5
Thread-0->6
Thread-0->7
Thread-0->8
Thread-0->9
main->1
main->2
main->3
main->4
main->5
main->6
main->7
main->8
main->9
应用场景:比如需要利用多个线程处理任务,然后统计所有线程执行完成后所花费的时间。代码中的join方法可以保证在三个线程执行完成后再将执行主线程中打印语句。
注意:在利用多线程处理任务时,并不是线程的数量越多越好,当线程数量到达一定程度时反而会使机器处理任务的速度变慢,因为线程之间的调度(上下文切换)会消耗CPU的资源。这时候可以利用线程组创建多个线程但是只让一定数量(使主机效率最高的线程数)的线程执行任务,其他处于wait状态(会释放掉CPU资源)。