使用示例:
import java.util.Random;
import java.util.concurrent.*;
class MyCallable implements Callable<Integer> {
private int i;
public MyCallable(int i) {
this.i = i;
}
@Override
public Integer call() throws Exception {
Random random = new Random();
Thread.sleep(random.nextInt(4000));
return i;
}
}
public class Main {
private static ExecutorService executor = Executors.newFixedThreadPool(5);
private static CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(executor);
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 多任务在线程池中并发执行,返回Future(阻塞队列+线程池)
for (int i = 0; i < 10; i++) {
completionService.submit(new MyCallable(i));
}
for (int i = 0; i < 10; i++) {
Future<Integer> future = completionService.take();
System.out.println(future.get());
}
// 线程池不关闭,jvm不会退出,因为线程池不属于后台守护线程
executor.shutdown();
}
}
源码:
public ExecutorCompletionService(Executor executor) {
if (executor == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ?
(AbstractExecutorService) executor : null;
// 无界队列
this.completionQueue = new LinkedBlockingQueue<Future<V>>();
}
submit():
private class QueueingFuture extends FutureTask<Void> {
QueueingFuture(RunnableFuture<V> task) {
super(task, null);
this.task = task;
}
// 将已完成的任务加入阻塞队列
protected void done() { completionQueue.add(task); }
private final Future<V> task;
}
public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
// 执行futureTask
executor.execute(new QueueingFuture(f));
// 返回futureTask
return f;
}
take():
public Future<V> take() throws InterruptedException {
return completionQueue.take();
}
线程池优点:
- 减少在创建和销毁线程上所花的时间以及系统资源的开销
- 如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”