当使用ExecutrorService返回多个Futrue时,需要获取时futrue中的多个返回值,我们一般把它放在队列中去,假如先放入的线程并没执行完,后放入的线程执行完了,我们还需要等待前一个线程执行完才可以获取返回的值,为什么我们不能哪个线程先执行完就先获取哪个线程返回的值呢?CompletionService就实现
下面我们可以用队列和CompletionService来对比一下
package cn.completionService;
import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class CompletionServiceCase {
private static int POOL_SIZE = Runtime.getRuntime().availableProcessors();
private static int TASK_COUNT = Runtime.getRuntime().availableProcessors();
public static void main(String[] args) throws ExecutionException, InterruptedException {
testQueue();
testComp();
}
public static void testQueue() throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE);
BlockingQueue<Future<Integer>> queue = new LinkedBlockingDeque<>();
AtomicInteger count = new AtomicInteger(0);
for (int i = 0; i < TASK_COUNT; i++) {
Future<Integer> f = pool.submit(new Task());
queue.put(f);
}
for (int i = 0; i < TASK_COUNT; i++) {
Integer stime = queue.take().get();
System.out.println("sleep time..." + stime + "....ms");
count.addAndGet(stime);
}
System.out.println("BlockingQueue------tasks sleep time---------"+count+"------耗时------"+(System.currentTimeMillis()-start));
pool.shutdown();
}
public static void testComp() throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
ExecutorService pool = Executors.newFixedThreadPool(POOL_SIZE);
ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<>(pool);
AtomicInteger count = new AtomicInteger(0);
for (int i = 0; i < TASK_COUNT; i++) {
completionService.submit(new Task());
}
for (int i = 0; i < TASK_COUNT; i++) {
int stime = completionService.take().get();
System.out.println("sleep time..." + stime + "....ms");
count.addAndGet(stime);
}
System.out.println("CompletionService-------tasks sleep time-------"+count+"------耗时------"+(System.currentTimeMillis()-start));
pool.shutdown();
}
}
class Task implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sleepTime = new Random().nextInt(10);
Thread.sleep(sleepTime);
return sleepTime;
}
}
执行结果