为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/ShiJiaqi。

https://www.cnblogs.com/shijiaqi1066/p/10454237.html

CompletionService是Java8的新增接口,JDK为其提供了一个实现类ExecutorCompletionService。这个类是为线程池中Task的执行结果服务的,即为Executor中Task返回Future而服务的。CompletionService的实现目标是任务先完成可优先获取到,即结果按照完成先后顺序排序。

CompletionService的使用非常简单。从源码查看ExecutorCompletionService类,该类只有三个成员变量:

public class ExecutorCompletionService<V> implements CompletionService<V> {
private final Executor executor;
private final AbstractExecutorService aes;
private final BlockingQueue<Future<V>> completionQueue; ...
}

可以看到ExecutorCompletionService主要是增强executor线程池的。Task包装后被塞入completionQueue,当Task结束,其Future就可以从completionQueue中获取到。

其基本原理可以参看下图:

CompletionService接口源码:

public interface CompletionService<V> {
// 提交
Future<V> submit(Callable<V> task);
Future<V> submit(Runnable task, V result);
// 获取
Future<V> take() throws InterruptedException;
Future<V> poll();
Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
}

例:向CompletionService中提交10个Task,当Task有任务返回则会优先从CompletionService内部的队列中获取到Task的Future。

package test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class TestCompletionService {
public static void main(String[] args) {
Long start = System.currentTimeMillis();
//开启3个线程
ExecutorService exs = Executors.newFixedThreadPool(5);
try {
int taskCount = 10;
// 结果集
List<Integer> list = new ArrayList<Integer>();
List<Future<Integer>> futureList = new ArrayList<Future<Integer>>(); // 1.定义CompletionService
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(exs); // 2.添加任务
for(int i=0;i<taskCount;i++){
Future<Integer> future = completionService.submit(new Task(i+1));
futureList.add(future);
} // 3.获取结果
for(int i=0;i<taskCount;i++){
Integer result = completionService.take().get();
System.out.println("任务i=="+result+"完成!"+new Date());
list.add(result);
} System.out.println("list="+list);
} catch (Exception e) {
e.printStackTrace();
} finally {
//关闭线程池
exs.shutdown();
} } static class Task implements Callable<Integer>{
Integer i; public Task(Integer i) {
super();
this.i=i;
} @Override
public Integer call() throws Exception {
if(i==5) {
Thread.sleep(5000);
}else{
Thread.sleep(1000);
}
System.out.println("线程:"+Thread.currentThread().getName()+"任务i="+i+",执行完成!");
return i;
} }
}

Java8的CompletionService使用与原理的更多相关文章

  1. 迄今为止最硬核的「Java8时间系统」设计原理与使用方法

    为了使本篇文章更容易让读者读懂,我特意写了上一篇<任何人都需要知道的「世界时间系统」构成原理,尤其开发人员>的科普文章.本文才是重点,绝对要读,走起! Java平台时间系统的设计方案 几乎 ...

  2. Java8线程池ThreadPoolExecutor底层原理及其源码解析

    小侃一下 日常开发中, 或许不会直接new线程或线程池, 但这些线程相关的基础或思想是非常重要的, 参考林迪效应; 就算没有直接用到, 可能间接也用到了类似的思想或原理, 例如tomcat, jett ...

  3. CompletionService简介、原理以及小案例

    博客1:http://www.oschina.net/question/12_11255 博客2: CompletionService简介 CompletionService与ExecutorServ ...

  4. 深入理解Java8中Stream的实现原理

    Stream Pipelines 前面我们已经学会如何使用Stream API,用起来真的很爽,但简洁的方法下面似乎隐藏着无尽的秘密,如此强大的API是如何实现的呢?比如Pipeline是怎么执行的, ...

  5. ☕【Java技术指南】「并发编程专题」CompletionService框架基本使用和原理探究(基础篇)

    前提概要 在开发过程中在使用多线程进行并行处理一些事情的时候,大部分场景在处理多线程并行执行任务的时候,可以通过List添加Future来获取执行结果,有时候我们是不需要获取任务的执行结果的,方便后面 ...

  6. 还在使用Future轮询获取结果吗?CompletionService快来了解下吧。

    背景 二胖上次写完参数校验(<二胖写参数校验的坎坷之路>)之后,领导一直不给他安排其他开发任务,就一直让他看看代码熟悉业务.二胖每天上班除了偶尔跟坐在隔壁的前端小姐姐聊聊天,就是看看这些 ...

  7. SpringBoot 2.x (7):拦截器

    类似以前SpringMVC的拦截器,但也有一些区别 SpringBoot的拦截器有两种方式: 第一种方式:过时的方式,适用于SpringBoot1.x的方式 package org.dreamtech ...

  8. [源码解析] 当 Java Stream 遇见 Flink

    [源码解析] 当 Java Stream 遇见 Flink 目录 [源码解析] 当 Java Stream 遇见 Flink 0x00 摘要 0x01 领域 1.1 Flink 1.2 Java St ...

  9. Java8 中 ConcurrentHashMap工作原理的要点分析

    简介: 本文主要介绍Java8中的并发容器ConcurrentHashMap的工作原理,和其它文章不同的是,本文重点分析了不同线程的各类并发操作如get,put,remove之间是如何同步的,以及这些 ...

随机推荐

  1. 500 G JAVA视频网盘分享(JEECG开源社区)

    500 G JAVA视频网盘分享(JEECG开源社区)   [涵盖从java入门到深入架构,Linux.云计算.分布式.大数据Hadoop.ios.Android.互联网技术应有尽有]   [转载:h ...

  2. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)

    1. 前言 最近在写毕设过程中,重新梳理了一遍SSM框架,特此记录一下. 附上源码:https://gitee.com/niceyoo/jeenotes-ssm 2. 概述 在写代码之前我们先了解一下 ...

  3. MongoDB 用户管理

    创建管理员账户: 1.登录 [root@MongoDB ~]# mongo 2.切换到admin数据库创建账户 > use admin switched to db admin 3.用户创建用户 ...

  4. 前端HTML目录

    前端 HTML 简介 前端 HTML文档结构介绍 前端 HTML文档 详解 前端 HTML 注释 前端 HTML标签介绍 前端 HTML的规范 前端 HTML 常用标签 head标签相关内容 前端 H ...

  5. Visual Studio 10.0设置引用HalconDotNet.dll

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u010435562/article/details/8858638 開始做Halcon的上位机.选用 ...

  6. js计算常见操作

    如何实现数字相加 var a = 1, var b = 2, var c = a + b 这样c得出来的解果是12, 使用Number()函数可以解决这个问题,如下 var c = Number(a) ...

  7. cxf简单例子

    cxf 这里介绍在web跟非web中的发布以及调用 准备条件: 1,导入cxf的相关jar包,以maven项目为例 pom的配置文件为 <project xmlns="http://m ...

  8. @property用法总结

    1.当方法需要传入别的参数时,不能定义成@property. 比如_table(self, owner)

  9. GitHub账户注册

    GitHub是一个优秀的面向开源及私有软件项目的托管平台,值得我们使用,但因为其不同于我们常见的很多平台,所以刚开始使用时,我们会遇到很多的问题.特此记录下博主自己使用GitHub的过程供自己以后查看 ...

  10. 实习培训——Java多线程(9)

    实习培训——Java多线程(9) 很适合新手 http://www.cnblogs.com/GarfieldEr007/p/5746362.html http://www.cnblogs.com/Ga ...