Thread 之 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 | @Slf4j public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info( "{} 线程启动" , Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep( 2 ); } catch (InterruptedException e) { e.printStackTrace(); } log.info( "{} 线程执行任务" , Thread.currentThread().getName()); }, "t1" ); Thread t2 = new Thread(() -> { log.info( "{} 线程启动" , Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep( 5 ); } catch (InterruptedException e) { e.printStackTrace(); } log.info( "{} 线程执行任务" , Thread.currentThread().getName()); }, "t2" ); t1.start(); t2.start(); log.info( "{} 线程执行任务" , Thread.currentThread().getName()); } } |
从上面的结果可以看出,main 线程首先获取到了 CPU 的时间片,然后执行,接着 t2 和 t1 获取到 CPU 时间片,获得执行
如果我们想 main 线程在 t1 和 t2 线程执行完任务之后再去执行 main 线程的任务,那该怎么办呢,这个时候就可以使用线程类提供的 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 32 33 | @Slf4j public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info( "{} 线程启动" , Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep( 2 ); } catch (InterruptedException e) { e.printStackTrace(); } log.info( "{} 线程执行任务" , Thread.currentThread().getName()); }, "t1" ); Thread t2 = new Thread(() -> { log.info( "{} 线程启动" , Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep( 5 ); } catch (InterruptedException e) { e.printStackTrace(); } log.info( "{} 线程执行任务" , Thread.currentThread().getName()); }, "t2" ); t1.start(); t2.start(); // 在主线程中分别调用 t1、t2 线程的 join() 方法,那么主线程就会等待 t1 和 t2 线程执行完毕之后再去执行主线程自身的任务 t1.join(); t2.join(); log.info( "{} 线程执行任务" , Thread.currentThread().getName()); } } |
使用 join 方法之后,main 线程会等待 t1、t2 线程执行完成自身的任务之后,接着才会去执行 main 线程的任务
上面我们使用的是 join() 的无参方法,无参的 join 方法实际上就是等价于 join(0)
接着我们看一下这个有参的 join 方法
如果传递进来的参数大于 0,底层实际上是调用 wait(delay),这个方法的作用是只会做有时限的等待,过时不候
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Slf4j public class JoinDemo { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(() -> { log.info( "{} 线程启动" , Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep( 5 ); } catch (InterruptedException e) { e.printStackTrace(); } log.info( "{} 线程执行任务" , Thread.currentThread().getName()); }, "t1" ); t1.start(); // 只会做有时限的等待,如果等待的时间超过了 t1 线程的执行时间,那么就不再继续等待了 t1.join( 2000 ); log.info( "{} 线程执行任务" , Thread.currentThread().getName()); } } |
从执行结果中可以看出,main 线程只等待了 2000ms,然后就开始执行 main 线程的任务去了,此时 t1 线程还没有执行完毕,main 线程就停止了等待
分类:
并发编程
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~