CompletionService与ExecutorService的区别与使用

如果对线程池不太了解请看《Thread线程系列之线程池介绍API的简介》《Thread线程系列之线程池详解》

CompletionService与ExecutorService都是属于线程池,都具备执行多线程的能力。但CompletionService执行多线程多任务时,那个任务优先执行完成,就会优先返回得到这个优先执行完任务的结果,以此类推。而ExecutorService执行多线程多任务时,是在当所有任务执行完之后,再一并返回结果。

看示例:

先看公共的任务类:

MyTask类:传递参数时间,且任务停顿相应的参数时间,再返回时间数;

public class MyTask implements Callable<Integer> {

    private Integer time;

    public MyTask(Integer time) {
        this.time = time;
    }

    @Override
    public Integer call() throws Exception {
        Thread.sleep(time); //暂停time秒
        return time; //返回time值
    }
}

数据定义:多任务集合

  //多任务集合myTaskList
    private static List<MyTask> getMyTaskList(){
        List<MyTask> myTaskList = new ArrayList<>();
        MyTask myTask1 = new MyTask(6 * 1000);
        MyTask myTask2 = new MyTask(3 * 1000);
        MyTask myTask3 = new MyTask(8 * 1000);
        MyTask myTask4 = new MyTask(1000);
        MyTask myTask5 = new MyTask(4 * 1000);
        myTaskList.add(myTask1);
        myTaskList.add(myTask2);
        myTaskList.add(myTask3);
        myTaskList.add(myTask4);
        myTaskList.add(myTask5);
        return myTaskList;
    }

1.看线程池(缓存型线程池)进行多任务执行的示例以及效果

 private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    private static final ExecutorService executorService = Executors.newCachedThreadPool();
    
    public static void main(String[] args) {

        long startTime = System.currentTimeMillis();

        testExecutorService(getMyTaskList());//缓存型线程池执行任务

        long endTime = System.currentTimeMillis();

        System.out.println("运行时间:" + (endTime - startTime)+"毫秒");
    }

    private static void testExecutorService(List<MyTask> myTaskList) {
        List<Future<Integer>> futureList = new ArrayList<>();
        for (MyTask myTask : myTaskList) {
            futureList.add(executorService.submit(myTask));
        }

        try {
            for (Future<Integer> future : futureList) {
                Integer result = future.get();
                System.out.println("结果\t"+sdf.format(new Date())+"\t"+result+"毫秒");
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }

    }

执行结果:(注意:开始运行时间与每个任务得到结果的时间的时间差【区别与CompletionService执行的结果

开始运行时间	18:35:27
结果	18:35:33	6000毫秒
结果	18:35:33	3000毫秒
结果	18:35:35	8000毫秒
结果	18:35:35	1000毫秒
结果	18:35:35	4000毫秒
运行时间:8048毫秒

2.看CompletionService进行多任务执行的示例以及效果

 private static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    private static final ExecutorService executorService = Executors.newCachedThreadPool();
    private static final CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);

    public static void main(String[] args) {

        System.out.println("开始运行时间\t"+sdf.format(new Date()));

        long startTime = System.currentTimeMillis();

        testCompletionService(getMyTaskList());//缓存型线程池执行任务

        long endTime = System.currentTimeMillis();

        System.out.println("运行时间:" + (endTime - startTime)+"毫秒");
    }


    private static void testCompletionService(List<MyTask> myTaskList) {
        for (MyTask myTask : myTaskList) {
            completionService.submit(myTask);
        }

        try {
            for (int i = 0; i < myTaskList.size(); i++) {
                Future<Integer> take = completionService.take();
                Integer result = take.get();
                System.out.println("结果\t"+sdf.format(new Date())+"\t"+result+"毫秒");
            }
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }finally {
            executorService.shutdown();
        }
    }

执行结果:(注意:开始运行时间与每个任务得到结果的时间的时间差【区别与ExecutorService执行的结果

扫描二维码关注公众号,回复: 4906402 查看本文章
开始运行时间	18:33:57
结果	18:33:58	1000毫秒
结果	18:34:00	3000毫秒
结果	18:34:01	4000毫秒
结果	18:34:03	6000毫秒
结果	18:34:05	8000毫秒
运行时间:8009毫秒

猜你喜欢

转载自blog.csdn.net/qq_33429583/article/details/84327581