package java.util.concurrent;
public class ExecutorCompletionService<V> implements CompletionService<V> {
//用来执行具体任务
private final Executor executor;
//用来封装Callable或Runnable对象
private final AbstractExecutorService aes;
//队列,用来存放已完成的任务
private final BlockingQueue<Future<V>> completionQueue;
//继承FutureTask,在发生done时把自己加入队列
//done方法不管是任务正常完成,还是取消,或者异常都会调用
private class QueueingFuture extends FutureTask<Void> {
QueueingFuture(RunnableFuture<V> task) {
super(task, null);
this.task = task;
}
//重写done方法,在任务完成后加入到队列
protected void done() { completionQueue.add(task); }
private final Future<V> task;
}
//包装Callable
private RunnableFuture<V> newTaskFor(Callable<V> task) {
if (aes == null)
return new FutureTask<V>(task);
else
return aes.newTaskFor(task);
}
//包装Runnable
private RunnableFuture<V> newTaskFor(Runnable task, V result) {
if (aes == null)
return new FutureTask<V>(task, result);
else
return aes.newTaskFor(task, result);
}
//构造参数传入Executor
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>>();
}
//构造参数传入Executor和队列
public ExecutorCompletionService(Executor executor,
BlockingQueue<Future<V>> completionQueue) {
if (executor == null || completionQueue == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ?
(AbstractExecutorService) executor : null;
this.completionQueue = completionQueue;
}
public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);
//提交一个任务,创建QueueingFuture进行封装,在任务状态切换后回调done方法,把自己加入队列
executor.execute(new QueueingFuture(f));
return f;
}
//提交一个任务,创建QueueingFuture进行封装,在任务状态切换后回调done方法,把自己加入队列
public Future<V> submit(Runnable task, V result) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task, result);
executor.execute(new QueueingFuture(f));
return f;
}
//获取并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则等待.
public Future<V> take() throws InterruptedException {
return completionQueue.take();
}
//获取已完成的任务并移除,如果不存在则返回null.
public Future<V> poll() {
return completionQueue.poll();
}
//获取已完成的任务并移除,如果不存在则等待,超时后返回null
public Future<V> poll(long timeout, TimeUnit unit)
throws InterruptedException {
return completionQueue.poll(timeout, unit);
}
}
等待所有任务完成的例子:
package com.ht.web.nio;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(Executors.newFixedThreadPool(10));
List<Callable<Integer>> list = new ArrayList<>();
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 1"); return 1;});
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 2"); return 2;});
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 3"); return 3;});
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 4"); return 4;});
for (Callable<Integer> callable : list) {
completionService.submit(callable);
}
for (int i = 0; i < list.size(); i++) {
Future<Integer> future = completionService.take();
System.out.println(future.isDone() + " + " + future.get());
}
}
}
只要有一个任务完成即可,结束其它任务:
package com.ht.web.nio;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(Executors.newFixedThreadPool(10));
List<Callable<Integer>> list = new ArrayList<>();
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 1"); return 1;});
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 2"); return 2;});
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 3"); return 3;});
list.add(() -> {Thread.sleep(3000); System.out.println(Thread.currentThread().getName() + "--> 4"); return 4;});
List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
for (Callable<Integer> callable : list) {
futures.add(completionService.submit(callable));
}
Integer result = null;
try {
for (int i = 0; i < list.size(); i++) {
Future<Integer> future = completionService.take();
if(future.get() != null) {
result = future.get();
break;
}
}
} finally {
for (int i = 0; i < futures.size(); i++) {
futures.get(i).cancel(true);
}
}
if(result != null) {
System.out.println(result);
}
}
}