找回密码
 立即注册
首页 业界区 业界 面试官:如何确保动态线程池任务都执行完? ...

面试官:如何确保动态线程池任务都执行完?

水苯 昨天 14:37
在 Java 并发编程中,线程池是提高系统吞吐量和响应速度的重要工具。
而是在高并发场景下,动态线程池(程序运行期间动态调整线程池参数而无需重启程序的技术)被广泛应用。然而,如何确保动态线程池中的所有任务都执行完毕,是一个常见的面试问题,也是实际开发中必须解决的关键问题。
所以,本文将深入探讨几种常见的方法,帮助开发者在实际项目中优雅地处理这个问题。
方法一:CountDownLatch

使用 CountDownLatch 来跟踪任务的完成情况,实现代码如下:
  1. // 动态线程池
  2. @Autowired
  3. @Qualifier("dtpExecutor1")
  4. private DtpExecutor dtpExecutor;
  5. @RequestMapping("isDone")
  6. public String isDone() throws InterruptedException {
  7.     // 申请计数器
  8.     CountDownLatch latch = new CountDownLatch(10);
  9.     for (int i = 0; i < 10; i++) {
  10.         dtpExecutor.submit(() -> {
  11.             try {
  12.                 Thread.sleep(1000);
  13.                 System.out.println("Task executed by " + Thread.currentThread().getName());
  14.             } catch (InterruptedException e) {
  15.                 Thread.currentThread().interrupt();
  16.             } finally {
  17.                 latch.countDown(); // 任务完成,计数器减1
  18.             }
  19.         });
  20.     }
  21.     // 等待所有任务完成
  22.     latch.await();
  23.     return "ok";
  24. }
复制代码
关键点


  • CountDownLatch:初始化时指定任务数量。每个任务完成后调用 countDown(),主线程调用 await() 等待所有任务完成。
  • 适用场景:适用于需要精确控制任务完成状态的场景,比如批处理任务、数据聚合等。
注意:CountDownLatch 是一次性的,不能重复使用;如果需要重复使用,可以考虑 CyclicBarrier。
方法二:CompletableFuture

从 Java 8 开始,CompletableFuture 提供了更强大的异步编程能力。它不仅支持 Future 的功能,还支持任务编排、组合、异常处理等高级特性。使用 CompletableFuture,可以更方便地管理多个异步任务的执行,并确保所有任务都完成。
我们可以借助 CompletableFuture 提供了 allOf() 方法,可以等待所有任务完成,具体实现代码如下:
  1. // 动态线程池
  2. @Autowired
  3. @Qualifier("dtpExecutor1")
  4. private DtpExecutor dtpExecutor;
  5. @RequestMapping("isDone")
  6. public String isDone() {
  7.     // 1.任务一
  8.     CompletableFuture future = CompletableFuture.runAsync(() -> {
  9.         // 执行业务逻辑
  10.     }, dtpExecutor);
  11.     // 2.任务二
  12.     CompletableFuture future2 = CompletableFuture.runAsync(() -> {
  13.         // 执行业务逻辑
  14.     }, dtpExecutor);
  15.     // 等待所有任务完成
  16.     CompletableFuture<Void> allTask = CompletableFuture.allOf(future, future2);
  17.     // 阻塞直到全部完成(无需结果)
  18.     allTask.join();
  19.     return "ok";
  20. }
复制代码
关键点


  • CompletableFuture.runAsync():异步执行任务,无任何返回值。指定动态线程池,避免使用默认的 ForkJoinPool。
  • allOf():等待所有任务完成。返回一个 CompletableFuture,调用 join() 或 get() 会阻塞,直到所有任务完成。
  • join():类似于 get(),但不会抛出检查异常,更适合在流式操作中使用。
小结

确保动态线程池中的所有任务都执行完毕,本文介绍了两种常见的方法:

  • CountDownLatch:适用于需要精确控制任务完成状态的场景。
  • CompletableFuture:适用于复杂异步任务编排、批量任务管理、异常处理和超时控制。
最后:面试官问这个问题,避免回答过于八股化和 AI 化。因此,在回答时,可以结合自己的具体项目模块实现来回答,要用自己的语言(非标准答案)表达出来。
本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:场景题、SpringAI、SpringAIAlibaba、并发编程、MySQL、Redis、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、JVM、设计模式、消息队列、Dify、Coze、AI常见面试题等。
   

关注公众号(加好友):

            
作者:        王磊的博客        
出处:        http://vipstone.cnblogs.com/        
   

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册