JDK的CompletionService提供了一种将生产新的异步任务与使用已完毕任务的结果分离开来的服务。生产者 submit 运行的任务。使用者 take 已完毕的任务,并依照完毕这些任务的顺序处理它们的结果。比如,CompletionService 能够用来管理异步 IO 。运行读操作的任务作为程序或系统的一部分提交,然后。当完毕读操作时,会在程序的不同部分运行其它操作,运行操作的顺序可能与所请求的顺序不同。

举个样例:如今要向server发送HTTP请求。服务端对于每一个请求都须要做非常多额外操作,非常消耗时间,则能够将每一个请求接受之后。提交到CompletionService异步处理,等运行完毕之后,在返回给client

package com.yf.concurrent;

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 CompletionServiceTest {
private ExecutorService threadPool = Executors.newCachedThreadPool();
private CompletionService<Response> completionService = new ExecutorCompletionService<Response>(
Executors.newCachedThreadPool()); public CompletionServiceTest() {
new Thread() {
public void run() {
while (true) {
try {
Future<Response> f = completionService.take();
/**
* 获取响应信息,返回给client
* 假设completionService任务队列为空,此处将堵塞
*/
Response resp = f.get();
System.out.println(resp.getId());
} catch (Exception e) {
System.out.println("Exception happened:"+e.getMessage());
}
}
};
}.start();
} class Request{
private int rid;
private String body;
public int getRid() {
return rid;
}
public void setRid(int rid) {
this.rid = rid;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
} class Response {
private int id;
private String body;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
} class HTTPExecutor {
public Future<Response> execute(final Request request) {
Future<Response> f = threadPool.submit(new Callable<Response>() {
public Response call() throws Exception {
Response response = new Response();
Thread.currentThread().sleep(3000);
response.setId(request.getRid());
response.setBody("response");
return response;
}
});
return f;
}
} public void submitHTTP(final Request request) {
completionService.submit(new Callable<Response>() {
public Response call() throws Exception {
return new HTTPExecutor().execute(request).get();
}
}); } public static void main(String[] args) { CompletionServiceTest t = new CompletionServiceTest();
for (int i = 0; i < 10; i++) {
/**
* 发送10个HTTP请求
*/
Request request =t.new Request();
request.setRid(i);
request.setBody("request");
t.submitHTTP(request);
} } }

能够简单查看一下CompletionService的唯一实现类ExecutorCompletionService源代码

关键代码例如以下:

public ExecutorCompletionService(Executor executor) {
if (executor == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ?
(AbstractExecutorService) executor : null;
this.completionQueue = new LinkedBlockingQueue<Future<V>>();
}
public ExecutorCompletionService(Executor executor,
BlockingQueue<Future<V>> completionQueue) {
if (executor == null || completionQueue == null)
throw new NullPointerException();
this.executor = executor;
this.aes = (executor instanceof AbstractExecutorService) ? (AbstractExecutorService) executor : null;
this.completionQueue = completionQueue;
} public Future<V> submit(Callable<V> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<V> f = newTaskFor(task);
executor.execute(new QueueingFuture(f));
return f;
}

通过ExecutorCompletionService的构造器可知,CompletionService 依赖于一个单独的 Executor 来实际运行任务。内部管理了一个堵塞队列来,在调用submit方法时。会向创建一个新的RunnableFuture,然后异步运行该RunnableFuture。当其状态变为done后,加入CompletionService的堵塞队列中,外部通过调用take()(堵塞)或者poll()(非堵塞,为空返回null)方法获取运行结果。

浅析Java CompletionService的更多相关文章

  1. 浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  2. 浅析Java.lang.Process类

    一.概述      Process类是一个抽象类(所有的方法均是抽象的),封装了一个进程(即一个执行程序).      Process 类提供了执行从进程输入.执行输出到进程.等待进程完成.检查进程的 ...

  3. 浅析Java中的访问权限控制

    浅析Java中的访问权限控制 今天我们来一起了解一下Java语言中的访问权限控制.在讨论访问权限控制之前,先来讨论一下为何需要访问权限控制.考虑两个场景: 场景1:工程师A编写了一个类ClassA,但 ...

  4. [转载]浅析Java中的final关键字

    浅析Java中的final关键字 谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来 ...

  5. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

  6. 浅析java内存管理机制

    内存管理是计算机编程中的一个重要问题,一般来说,内存管理主要包括内存分配和内存回收两个部分.不同的编程语言有不同的内存管理机制,本文在对比C++和Java语言内存管理机制的不同的基础上,浅析java中 ...

  7. 【转】浅析Java中的final关键字

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. ...

  8. 浅析 java ArrayList

    浅析 java ArrayList 简介 容器是java提供的一些列的数据结构,也可以叫语法糖.容器就是用来装在其他类型数据的数据结构. ArrayList是数组列表所以他继承了数组的优缺点.同时他也 ...

  9. [转帖]浅析java程序的执行过程

    浅析java程序的执行过程 转帖来源: https://www.cnblogs.com/wangjiming/p/10315983.html 之前学习过 这一块东西 但是感觉理解的不深刻. copy一 ...

随机推荐

  1. 【JavaScript 从零开始】表达式和运算符(2)

    in运算符 in运算符希望它的左操作数是一个字符串或可以转换为字符串,希望它的右操作数是一个对象. 如果右侧的对象拥有一个名为做操作数值的属性名,那么表达式返回true,例如: var point= ...

  2. 【模板】 全排列 && 有重复元素的全排列

    全排列 #include<bits/stdc++.h> using namespace std; ]; void print (int n){ ;i<=n;i++) cout< ...

  3. [android] 手机卫士黑名单功能(列表展示)

    先把要拦截的电话号码保存到数据库中,拦截模式用个字段区分,1 电话拦截,2 短信拦截,3全部拦截 新建Activity类CallSmsSafeActivity.java 新建布局文件activity_ ...

  4. SpringMVC中properties文件读取

    SpringMVC给我们提供了用于properties文件读取的类: org.springframework.context.support.ResourceBundleMessageSource 1 ...

  5. CDN和镜像站点比较

      CDN和镜像站点是常用的提高网站访问速度的两种方式,但这两种方式具体是什么.二者间有什么相同和不同之处,本文对此做一粗浅介绍. 一.镜像站点 1.1定义 镜像网站是指将一个完全相同的网站源程序放到 ...

  6. 分布式理论基础(一)一致性及解决一致性的两种方式:2PC和3PC (转载 不错)

    分布式理论基础(一)一致性及解决一致性的两种方式:2PC和3PC 1 一致性 1.1 简述 一致性,是指对每个节点一个数据的更新,整个集群都知道更新,并且是一致的 假设一个具有N个节点的分布式系统,当 ...

  7. PHP生成缩略图(2)--等比缩略图

    分析: 当原图是横屏或竖屏的时候,希望缩略图会保持原来的比例缩放,不改变原图的完整性,即等比缩放! 此时只需确定原图的宽高,以及目标图的最大宽高,比较目标图的宽高比例与原图的宽高比例的大小,以此来判断 ...

  8. 移动端h5实现拍照上传图片并预览&webuploader

    .移动端实现图片上传并预览,用到h5的input的file属性及filereader对象:经测除了android上不支持多图片上传,其他基本ok实用: 一:先说一下单张图片上传(先上代码): html ...

  9. angular2上传图片

    话不多说,直接写 一.html页面 二.html代码:   <div class="descright"> <div class="clinic-img ...

  10. maven 安装下载与配置 代理设置 《解决下载慢问题》

    maven:下载地址http://mirror.bit.edu.cn/apache/maven/maven-3/ 解压之后配置环境 %maven_home%  d:\*****path 中添加 %ma ...