• java concurrent 中ExecutorService和CompletionService简单区别


    举个例子,现在需要执行10个任务,这些任务都是有返回值,并且需要使用10个线程同时执行。一般的做法就是创建ExecutorService线程池,pool大小10,每个任务实现Callable接口,然后执行使用List保存每个线程的Future结果,然后遍历这个List,取出future,然后使用.get()获取执行的结果。
    (1)
    ExecutorService**的处理就是使用list存

    //伪代码
    ExecutorService executor = Executors.newFixedThreadPool(10);
    List<Future<Object>> futureList = new ArrayList<Future<String>>();
    for(int i = 0 ; i<10; i++){
       Future<Object> future  = executor.submit( 任务i );
       futureList.add(future); 
    }
    
     遍历futureList获取future调用.get()获取结果
    

    但是会发现一个问题,假设任务标号1-10一次执行,所以放入list中的future也是标号1-10,在遍历list的过程中,如果任务4完成了,任务2还没有完成,那么就会一直阻塞在任务2的future.get()中,其实后面的任务可能已经做完了,但是还是要等前面的任务得到结果。

    (2)CompletionService的处理

             ExecutorService executor = Executors.newFixedThreadPool(numThread);
            CompletionService<String> completionService = new ExecutorCompletionService<String>(executor);
            for(int i = 0;i<numThread;i++ ){
                completionService.submit任务 i );
            }
            for(int i = 0;i<numThread;i++ ){
                completionService.take().get();
            }
    
    

    CompletionService的效果则是,哪个任务先完成则取出哪个任务的结果,其实现原理是使用BlockingQueue来保存future,只有当future对应的某个任务执行结束,可以获取结果后,才会把这个future放入到BlockingQueue中,completionService.take()操作则是取出BlockingQueue的future,如果BlockingQueue中还没有结果,则take()方法阻塞,等待有结果,一旦有结果放入则取出。CompletionService快,可以节省时间,但是不能保证结果处理顺序。

  • 相关阅读:
    四十九、在SAP中查看程序资源结构对象
    四十八、在SAP中函数参数的使用
    四十七、在SAP中,把功能区块整合成一个函数,通过调用函数的办法使代码简洁明了
    四十六、SAP的Message中E和W区别
    四十五、SAP中Message的管理
    四十四、在SAP中冻结第一行表头
    四十三、在SAP中初始化勾选值
    四十二、在SAP中添加单选框
    四十一、在SAP中添加多条件选择框
    四十、SAP中CASE语句用法
  • 原文地址:https://www.cnblogs.com/hts-technology/p/9303960.html
Copyright © 2020-2023  润新知