携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
ExecutorCompletionService的take()方法具有阻塞特性
修改运行类执行代码如下:
@Slf4j
public class FutureRun {
public static void main(String[] args) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");
FutureCallable g1 = new FutureCallable("G1", 5000L);
FutureCallable g2 = new FutureCallable("G2", 4000L);
FutureCallable g3 = new FutureCallable("G3", 3000L);
FutureCallable g4 = new FutureCallable("G4", 2000L);
FutureCallable g5 = new FutureCallable("G5", 1000L);
ArrayList<Callable> callableArrayList = new ArrayList<>();
callableArrayList.add(g1);
callableArrayList.add(g2);
callableArrayList.add(g3);
callableArrayList.add(g4);
callableArrayList.add(g5);
ArrayList<Future> futureArrayList = new ArrayList<>();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 10, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
//使用CompletionService
ExecutorCompletionService executorCompletionService = new ExecutorCompletionService(threadPoolExecutor);
for (int i = 0; i < 5 ; i++) {
executorCompletionService.submit(callableArrayList.get(i));
}
for (int i = 0; i < 6 ; i++) {
try {
log.info("等待输出第{}个",i+1);
log.info("返回值:{}",executorCompletionService.take().get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
运行结果如下:
[pool-1-thread-5] INFO com.ozx.concurrentprogram.executor.service.FutureCallable - 用户名:G5
[pool-1-thread-3] INFO com.ozx.concurrentprogram.executor.service.FutureCallable - 用户名:G3
[pool-1-thread-2] INFO com.ozx.concurrentprogram.executor.service.FutureCallable - 用户名:G2
[pool-1-thread-4] INFO com.ozx.concurrentprogram.executor.service.FutureCallable - 用户名:G4
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 等待输出第1个
[pool-1-thread-1] INFO com.ozx.concurrentprogram.executor.service.FutureCallable - 用户名:G1
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 返回值:G5
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 等待输出第2个
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 返回值:G4
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 等待输出第3个
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 返回值:G3
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 等待输出第4个
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 返回值:G2
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 等待输出第5个
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 返回值:G1
[main] INFO com.ozx.concurrentprogram.executor.controller.FutureRun - 等待输出第6个
从运行结果看出将循环次数修改为6次,线程池执行5个任务后一直在等待阻塞着,所以在CompletionService接口中如果当前没有任务被执行完,CompletionService.take().get()的方法还是处于阻塞状态。
ExecutorCompletionService使用take()方法
take()方法取得最先完成任务的Future对象,哪个任务先执行时间最短哪个任务最先返回。