Java多线程ExecutorService中Future.isDone()始终不返回true无输出问题
问题根因
你提交Callable任务后立刻执行submitResults.isDone()判断,此时任务还处于300毫秒的休眠执行阶段,isDone()直接返回false,打印逻辑完全不会被触发。后续你等待线程池终止的逻辑也不会回头执行打印判断,所以控制台无输出。
另外你贴出的代码末尾多了一个多余的闭合大括号,属于语法错误,运行前需要先删除。
修复方案
下面是三种常见的修复方式,按需选择即可:
- 方案1:直接阻塞获取结果(最符合Future常规使用场景)
Future.get()本身会阻塞当前线程直到任务执行完成,直接替换原有判断逻辑即可,不需要额外判断isDone():
// 原有if(submitResults.isDone())的代码块替换为下面这行 System.out.println(submitResults.get());
- 方案2:轮询判断任务状态(适合提交任务后需要同时处理其他逻辑的场景)
如果你提交任务后还要执行其他异步操作,可以加轮询判断任务是否完成:
// 提交任务后先处理其他逻辑... // 轮询等待任务完成 while (!submitResults.isDone()) { // 可以加短时休眠避免空轮询占满CPU TimeUnit.MILLISECONDS.sleep(50); } System.out.println(submitResults.get());
- 方案3:等待线程池终止后再获取结果
你已经配置了800毫秒的线程池终止等待时间,远大于任务300毫秒的执行时长,把打印逻辑移到awaitTermination之后即可:
service.shutdown(); if(!service.awaitTermination(800,TimeUnit.MILLISECONDS)) { service.shutdownNow(); } // 线程池终止后任务必然已经结束,直接判断/获取结果即可 if(submitResults.isDone()) { System.out.println(submitResults.get()); }
完整修复后示例代码
import java.util.concurrent.*; public class FuturesExample { public static void main(String[] args) { FuturesExample.executeThreadScheduler(); } static void executeThreadScheduler() { ExecutorService service = Executors.newFixedThreadPool(10); Callable<String> callableTask = ()->{ TimeUnit.MILLISECONDS.sleep(300); return "Task Executed" ; }; Future<String> submitResults = service.submit(callableTask); try { // 这里用方案1的写法,直接阻塞拿结果 System.out.println(submitResults.get()); service.shutdown(); if(!service.awaitTermination(800,TimeUnit.MILLISECONDS)) { service.shutdownNow(); } } catch (InterruptedException e) { service.shutdownNow(); e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者Abdulmalik Mahasneh
相关产品推荐
相关产品推荐

