ExecutorService
使用ExecutorService提交多个任务时,需要保存Callable对应的Future。
需要反复循环判断future是否完成。
@Test
public void test() throws InterruptedException {
LinkedBlockingQueue<Future<String>> futures = new LinkedBlockingQueue<>();
Random random = new Random();
ExecutorService pool = Executors.newFixedThreadPool(5);
Thread producerThread = new Thread(){
@Override
public void run() {
for (int i = 0; i < 10; i++) {
int finalI = i;
Future<String> future = pool.submit(new Callable<String>() {
@Override
public String call() throws Exception {
int time = random.nextInt(10000);
Thread.sleep(time);
return "task_" + finalI;
}
});
System.out.println("submit_" + i);
futures.add(future);
}
}
};
producerThread.start();
Thread consumerThread = new Thread(){
@Override
public void run() {
while (true) {
for (Future<String> future : futures) {
if (future.isDone()) {
try {
System.out.println(future.get());
futures.remove(future);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}
}
};
consumerThread.start();
producerThread.join();
consumerThread.join();
}
CompletionService 获取结果
使用CompletionService可以简化操作。
@Test
public void test2() throws InterruptedException {
//LinkedBlockingQueue<Future<String>> futures = new LinkedBlockingQueue<>();
Random random = new Random();
ExecutorService pool = Executors.newFixedThreadPool(5);
//使用ExecutorCompletionService包装ExecutorService
ExecutorCompletionService<String> completionService = new ExecutorCompletionService<String>(pool);
Thread producerThread = new Thread(){
@Override
public void run() {
for (int i = 0; i < 10; i++) {
int finalI = i;
//Future<String> future = pool.submit(new Callable<String>() {
completionService.submit(new Callable<String>() {
@Override
public String call() throws Exception {
int time = random.nextInt(10000);
Thread.sleep(time);
return "task_" + finalI;
}
});
System.out.println("submit_" + i);
//futures.add(future);
}
}
};
producerThread.start();
Thread consumerThread = new Thread(){
@Override
public void run() {
while (true) {
try {
Future<String> take = completionService.take();
System.out.println(take.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
/*while (true) {
for (Future<String> future : futures) {
if (future.isDone()) {
try {
System.out.println(future.get());
futures.remove(future);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
}*/
}
};
consumerThread.start();
producerThread.join();
consumerThread.join();
}
CompletionService 原理
构造方法
//构造方法
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>>();
}
初始化自身属性:
- this.executor 真正的线程池
- this.completionQueue 保存执行完成的future执行结果的阻塞队列
submit
public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);
//包装成QueueingFuture,传递给executor
executor.execute(new QueueingFuture(f));
return f;
}
QueueingFuture
ExecutorCompletionService中的内部类
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;
}
重写done方法,将task添加到completionQueue。completionQueue是ExecutorCompletionService中的属性。所以,执行完一个任务,就将执行完的RunnableFuture添加到ExecutorCompletionService的阻塞队列completionQueue中。
take
public Future<V> take() throws InterruptedException {
return completionQueue.take();
}
而take操作就是从阻塞队列中取出,已经完成的任务结果(RunnableFuture)。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。