【Java】CompletionService 使用
来源:互联网 发布:java视频教程数组 编辑:程序博客网 时间:2024/06/07 05:44
使用线程池的submit方法时,可以返回一个Future,我们可以通过这个Future来获得任务的返回值。那么通常的场景是,我们通过多个任务来获取到了返回值,之后就需要对返回值进行处理,此时我们需要把每一个Future放进一个容器里,然后用一个循环处理。不过这里还是有问题的,我们知道通常的容器是不允许一边读取,一边修改的,会抛出一个ConcurrentModificationExceptoin,一般的容器遍历都是静态的,但是这里的容器却不是,它时时刻刻都有可能被放入一个结果,但是什么时候谁也不知道,而且它有可能是是空的。所以这个容器与以往的场景不同。我们需要支持之前提到的特性。
这其实就是CompletionService的用途,它已经为我们维护了这个队列,它会自动把执行完的任务结果放入队列中,我们可以使用take方法或者poll来获取结果。take在队列为空时会被阻塞,而poll返回null。这样我们编写上述代码就会简单得多,不同再去担心自己维护一个结果的队列的。
下面是一个UI中很常见的例子,异步加载不同的资源,像文本这种的我们可以直接渲染,但是图片这种的,我们需要先下载然后加载,可以让每一个下载异步执行,把结果放入一个队列,再从队列里面拿下好的图片渲染。
package ThreadTest;import java.util.concurrent.Callable;import java.util.concurrent.CompletionService;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorCompletionService;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class PageRender {public void rend(Source source){ExecutorService e = Executors.newFixedThreadPool(10);CompletionService<Image> ce = new ExecutorCompletionService<Image>(e);for(String url : source.urls){ce.submit(new Callable<Image>() {@Overridepublic Image call() throws Exception {return download(url);}});}rendTxt(source.txt);for(int i = 0 ; i < source.urls.size(); i++){try {Future<Image> future = ce.take();Image img = future.get();rendImage(img);} catch (InterruptedException e1) {e1.printStackTrace();} catch (ExecutionException e1) {e1.printStackTrace();}}e.shutdown();}Image download(String url){System.out.println("download Image" + url);try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}return new Image();}void rendTxt(String txt){System.out.println("rendTxt");}void rendImage(Image img){System.out.println("rendImage");}}
public static void main(String[] args) {PageRender pr = new PageRender();Source source = new Source();List<String> list = new ArrayList<>();for(int i = 0 ; i < 10; i++){list.add("url " + i);}source.urls = list;source.txt = "Hello";pr.rend(source);}结果:
download Imageurl 0
download Imageurl 2
download Imageurl 3
download Imageurl 1
download Imageurl 4
download Imageurl 5
download Imageurl 6
download Imageurl 7
rendTxt
download Imageurl 9
download Imageurl 8
rendImage
rendImage
rendImage
rendImage
rendImage
rendImage
rendImage
rendImage
rendImage
rendImage
- 【Java】CompletionService 使用
- Java多线程--CompletionService的使用
- CompletionService使用
- java-CompletionService
- JAVA多线程—CompletionService的使用介绍
- java并发:ExecutorServiec中的CompletionService和invokeAll的使用
- Java并发编程核心方法与框架-CompletionService的使用
- 使用CompletionService批处理任务(java并发编程第6章)
- 【Java并发】- 使用CompletionService异步收集任务结果
- 使用CompletionService批处理任务
- 多线程之CompletionService使用
- 使用CompletionService批处理任务
- 使用CompletionService批处理任务
- completionService的使用
- java concurrent之CompletionService
- Java之CompletionService
- Java线程之CompletionService
- JAVA CallableAndFuture CompletionService
- 纳兰传奇人生里的情深意短
- 神经机器翻译(Neural Machine Translation)系列教程
- MySQL_函数GROUP_CONCAT_合并多行数据到一行
- 安装激活 Mindjet MindManager
- 小声哔哔
- 【Java】CompletionService 使用
- 神经机器翻译(Neural Machine Translation)系列教程
- LeetCode编程练习
- AbstractQueuedSynchronizer的介绍和原理分析
- LeetCode编程练习
- Fragment知识点,一篇搞定!
- LeetCode编程练习
- LeetCode编程练习
- LeetCode编程练习