当使用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;
    }
}

执行结果

CompletionService优于ExecutorService

 

 

分类:

技术点:

相关文章: