赞
踩
Thread thread = new Thread(“[test] thread”);
thread.start();
thread.join();
比如当子线程中业务逻辑处理的时间很长时,那么主线程就会先于子线程提前结束,而如果想要主线程在子线程处理完以后再结束(比如需要子线程中返回的数据),那就可以使用 Thread threadSon.join();
join()上面的解释:
Waits for this thread to die.
当前线程指得是子线程,即阻塞主线程继续执行,直到子线程处理结束;
public class ThreadTest { public static void main(String[] args) throws InterruptedException { String mainThread = Thread.currentThread().getName(); System.out.println(mainThread + " start.."); ThreadB threadB = new ThreadB(); threadB.start(); threadB.join(); System.out.println(mainThread + " end.."); } } public class ThreadB extends Thread { public ThreadB() { super("[ThreadB] thread"); } public void run() { String threadName = Thread.currentThread().getName(); System.out.println(threadName + " start.."); for(int i=0;i<5;i++) { System.out.println(threadName + " loop at 0" + i); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(threadName + " end.."); } }
执行结果:
main start..
[ThreadB] thread start..
[ThreadB] thread loop at 00
[ThreadB] thread loop at 01
[ThreadB] thread loop at 02
[ThreadB] thread loop at 03
[ThreadB] thread loop at 04
[ThreadB] thread end..
main end..
jdk中join()的源码:
public final void join() throws InterruptedException {
join(0);
}
主要是接下来的 join(long millis)
/** * Waits at most {@code millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. */ public final synchronized void join(long millis) //注意这里的synchronized throws InterruptedException { long base = System.currentTimeMillis(); long now = 0; if (millis < 0) { throw new IllegalArgumentException("timeout value is negative"); } //如果millis为0的话,只要线程(上面的子线程ThreadB)还活着,就会调用wait(0)阻塞当前线程, //一直到threadB执行结束;(wait(0)相当于持有threadB线程的锁然后等待) if (millis == 0) { while (isAlive()) { wait(0); } } else { while (isAlive()) { long delay = millis - now; if (delay <= 0) { break; } wait(delay); now = System.currentTimeMillis() - base; } } }
我刚刚是在springboot启动过程中的源码才注意到的():
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
//看到了这里
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
然后跟着context.registerShutdownHook();继续挖掘,直到看到了这个类ApplicationShutdownHooks,它里面的runHooks()方法如下:
static void runHooks() { Collection<Thread> threads; synchronized(ApplicationShutdownHooks.class) { threads = hooks.keySet(); hooks = null; } for (Thread hook : threads) { hook.start(); } for (Thread hook : threads) { try { //看到了这个join()方法 hook.join(); } catch (InterruptedException x) { } } }
然后就深入地了解下join()方法,从一个地方拓展到其他地方;
我以前也有过类似需要等待子线程执行完,然后执行主线程的需求,当时应该是直接让主线程等待的。。然后再看去探查指定的指标是否完成……有了这个threadB.join()方法,这样就合理多了,避免了主线程等待时的空自旋;
https://blog.csdn.net/sinat_29384657/article/details/52228578
https://zhuanlan.zhihu.com/p/258581678
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。