CompletionService是一个异步处理模式,其主要的功能是可以异步获取线程池的返回结果。CompletionService将Executor(线程池)和BlockingQueue(阻塞队列)结合在一起,同时主要使用Callable定义线程任务。整个操作中就是生产者不断地将Callable线程任务保存进阻塞队列,而后线程池作为消费者不断地把线程池中的任务取出,并且返回结果。
CompletionService接口可以接收Callable或Runnable实现的线程任务,并且可以通过ExecutorCompletionService子类实例化接口对象。
1、使用CompletionService接口获取异步执行任务结果的例子【该程序通过CompletionService基于已有的线程池构建了一个异步任务,由于其内部会自动维护一个阻塞队列,这样所有的Callable任务执行完成后就可以通过take()方法获取线程任务执行结果】:
package com.mydemo;
import java.util.concurrent.*;
public class JUCDemo {
public static void main(String[] args) throws Exception {
// 创建线程池
ExecutorService executorService = Executors.newCachedThreadPool();
// 创建一个异步处理任务,并且该异步任务需要一个线程池实例
CompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
// 信息生产者
for(int i = 0; i < 10; i++){
// 提交线程
completionService.submit(new ThreadItem());
}
// 获取结果
for(int i = 0; i < 10; i++){
System.out.println("获取数据:" + completionService.take().get());
}
// 关闭线程
executorService.shutdown();
}
}
// 线程体
class ThreadItem implements Callable<String>{
@Override
public String call() throws Exception {
// 当前时间戳
long timeMillis = System.currentTimeMillis();
System.out.println("【START】" + Thread.currentThread().getName());
Thread.sleep(1000);
System.out.println("【END】" + Thread.currentThread().getName());
return Thread.currentThread().getName() + " :" + timeMillis;
}
}