completionService
我们现在在Java中使用多线程通常不会直接用Thread对象了,而是会用到java.util.concurrent包下的ExecutorService类来初始化一个线程池供我们使用。
当我们使用ExecutorService来做多线程处理时,习惯自己维护一个list保存submit的callable task所返回的Future对象。
然后在主线程中遍历这个list并调用Future的get()方法取到Task的返回值。
这两者最主要的区别在于submit的task不一定是按照加入自己维护的list顺序完成的。
从list中遍历的每个Future对象并不一定处于完成状态,这时调用get()方法就会被阻塞住,如果系统是设计成每个线程完成后就能根据其结果继续做后面的事,这样对于处于list后面的但是先完成的线程就会增加了额外的等待时间。
比如:浏览器在渲染某个页面时,需要下载很多图片,我们把下载图片放到ExecutorService的tast里面处理,这样我们只能按照放入list的图片顺序来渲染图片,如果有些图片比较大,又比较早的被放入的提交的list<task>,这时候就比较影响用户体验了。
如果我们改用completionService,那就可以通过调用completionService.take(),达到只有有图片下载成功,我们就可以优先渲染(展示)这张图片的目的(我想浏览器应该也是按照逻辑来设计的吧)。
我们来看下CompletionService的一个具体实现的一个具体实现ExecutorCompletionService,
1、private final BlockingQueue<Future<V>> completionQueue; //维护一个阻塞队列
2、protected void done() { completionQueue.add(task); }//当某个task完成的时候,就把该task放入队列中
3、public Future<V> take() throws InterruptedException {
return completionQueue.take();
} //从阻塞队列中拿到已经完成的task
这样整个功能就很清晰了。
completionService的更多相关文章
- Java批处理ExecutorService/CompletionService
服务端接收一个请求,常常需要同时进行几个计算或者向其他服务发送请求,最后拼装结果返回上游.本文就来看下JDK提供几个并行处理方案,牵涉到ExcecutorService/CompletionServi ...
- CompletionService/ExecutorCompletionService/线程池/concurrent包
线程池 线程池的基本思想:线程频繁的创建.销毁会极大地占用系统资源,为了减少系统在创建销毁线程时的开销,线程池应运而生.线程池包括多个已创建的线程,当有任务要在新线程中执行时,将任务提交给线程池,线程 ...
- Java并发编程核心方法与框架-CompletionService的使用
接口CompletionService的功能是以异步的方式一边生产新的任务,一边处理已完成任务的结果,这样可以将执行任务与处理任务分离.使用submit()执行任务,使用take取得已完成的任务,并按 ...
- Java中ExecutorService和CompletionService区别
我们现在在Java中使用多线程通常不会直接用Thread对象了,而是会用到java.util.concurrent包下的ExecutorService类来初始化一个线程池供我们使用. 之前我一直习惯自 ...
- 线程池ExecutorService和完成服务CompletionService的使用获取线程的返回结果
package com.suning.ecif.admin.app.impl.temp; import java.util.ArrayList;import java.util.Collection; ...
- 并发编程 06—— CompletionService :Executor 和 BlockingQueue
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- java核心知识点学习----创建线程的第三种方式Callable和Future CompletionService
前面已经指出通过实现Runnable时,Thread类的作用就是将run()方法包装成线程执行体,那么是否可以直接把任意方法都包装成线程执行体呢?Java目前不行,但其模仿者C#中是可以的. Call ...
- Java线程之CompletionService
转自:http://blog.csdn.net/andycpp/article/details/8902699 当使用ExecutorService启动了多个Callable后,每个Callable会 ...
- Callable与Future、FutureTask的学习 & ExecutorServer 与 CompletionService 学习 & Java异常处理-重要
Callable是Java里面与Runnable经常放在一起说的接口. Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务 ...
随机推荐
- Python函数讲解
Python函数
- PHP PDO的setAttribute函数
数据库的连接: $dsn = 'mysql:host=127.0.0.1;port=3306;dbname=cardslg'; $username = 'root'; $password = ''; ...
- cf593d
题意:给出一个有n(n<=200000)的树形图,每条边有一个权值.有两种操作,1是将一个边的权值变小, 2是给定两点a,b和一个值y,用y(long long范围内)依次除以两点之间的路径上的 ...
- appium 处理动态控件
环境怎么搭建,参考:http://www.cnblogs.com/tobecrazy/p/4562199.html 知乎Android客户端登陆:http://www.cnblogs.com/tobe ...
- jquery ajax 请求参数详细说明 及 实例
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- CSS 魔法系列:纯 CSS 绘制三角形(各种角度)
我们的网页因为 CSS 而呈现千变万化的风格.这一看似简单的样式语言在使用中非常灵活,只要你发挥创意就能实现很多比人想象不到的效果.特别是随着 CSS3 的广泛使用,更多新奇的 CSS 作品涌现出来. ...
- go:interface{}、断言与类型转换
interface{}可用于向函数传递任意类型的变量,但对于函数内部,该变量仍然为interface{}类型(空接口类型), 不清楚这点将可能导致错误.如以下代码: package main impo ...
- Linux常用命令学习5---(Shell编程)
1.Shell概述 Shell是一个命令行解释器.它为用户提供了一个向Linux内核发送请求一以便运行程序的界面系统级程序,用户可以用 Shell来启动.挂起.停止甚至是编写一些程序 Sh ...
- for循环中i--的妙用 及 两变量互换数值的问题
int[] array = new int[4]; for(int i = 0; i < array.length; i++){ array[i] = (int)(Math.random() * ...
- php调试
转自:http://www.cnblogs.com/gidot/p/4307709.html