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执行的结果

开始运行时间	18:33:57
结果	18:33:58	1000毫秒
结果	18:34:00	3000毫秒
结果	18:34:01	4000毫秒
结果	18:34:03	6000毫秒
结果	18:34:05	8000毫秒
运行时间:8009毫秒

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值