等待线程结束(join)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了等待线程结束(join)相关的知识,希望对你有一定的参考价值。
很多情况下,线程之间的协作和人与人之间的协作非常相似。一种非常常见的合作方式就是分工合作。以我们非常熟悉的软件开发为例,在一个项目进行时,总是应该有几位号称是“需求分析师”的同事,先对系统的需求和功能点进行整理和总结,然后,以书面形式给出一份需求说明或者类似的参考文档,然后,软件设计师,研发工程师才会一拥而上,进行软件开发。如果缺少需求分析师的工作输出,那么软件研发的难度可能会比较大。因此,作为一名软件研发人员,总是喜欢等待需求分析师完成他应该完成的任务后,才愿意投身工作。简单地说,就是研发人员需要等待需求分析师完成他的工作,然后,才能进行研发。
将这个关系对应到多线程应用中,很多时候,一个线程的输入可能非常依赖于另外一个或者多个线程的输出,此时,这个线程就需要等待依赖线程执行完毕,才能继续执行,JDK提供了join()操作来实现这个功能。下边显示两个join方法:
public final void join() throws InterruptedException public final synchronized void join(long millis) throws InterruptedException
第一个join方法表示无线等待,他会一直阻塞当前线程,知道目标线程执行完毕。第二个方法给出了一个最大等待时间,如果超过给定时间目标线程还在执行,当前线程也会因为“等待不及了”,而继续往下执行。
英文join的翻译,通常是加入的意思。在这里感觉也非常贴切。因为一个线程要加入另外一个线程,那么最好的方法就是等着它一起走。
这里提供一个join实例:
public class JoinMain{ public volatile static int i = 0 ; public static class AddThread extends Thread{ public void run(){ for(i=0;i<10000000;i++); } } public static void main(String args[]) throws InterruptedException{ AddThread at = new AddThread(); at.start(); at.join(); System.out.println(i); } }
主函数中,如果不使用join()等待AddThread,那么得到的i很可能是0或者一个非常小的数字。因为AddThread还没开始执行,i的值就已经呗输出了。但在使用join()方法后,表示主线程愿意等待AddThread执行完毕,跟着AddThread一起往前走,故在join()返回时,AddThread已执行完成,故i总是10000000.
有关于join().我还想再补充一点,join()的本质是让调用线程wait()在当前线程对象实例上。下面是JDK中join()实现的核心代码片段
while(isAlive()){ wait(0); }
可以看到,它让调用线程在当前线程对象上进行等待。当线程执行完成后,被等待的线程会在退出前调用notifyAll()通知所有的等待线程继续执行。因此,值得注意的一点是:不要在应用程序中,在Thread对象实例上使用类似wait()或者notify()等方法,因为这很有可能会影响系统API的工作或者被系统API影响。
以上是关于等待线程结束(join)的主要内容,如果未能解决你的问题,请参考以下文章
JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段
java 并发多线程 : 主线程等待子线程结束的三种方式:join / CountDownLatch / CyclicBarrier