CompletionService--实现并行获取future.get()结果

CompletionService实际上可以看做是Executor和BlockingQueue的结合体。CompletionService在接收到要执行的任务时,通过类似BlockingQueue的put和take获得任务执行的结果。

CompletionService的一个实现是ExecutorCompletionService,ExecutorCompletionService把具体的计算任务交给Executor完成。

 

异步下载图片,并实时渲染已下载图片的代码样例,通过将结果加入阻塞队列的方式来绕过异步结果Future.get()的等待问题

 1 package net.jcip.examples;
 2 
 3 import java.util.*;
 4 import java.util.concurrent.*;
 5 import static net.jcip.examples.LaunderThrowable.launderThrowable;
 6 
 7 /**
 8  * Renderer
 9  * <p/>
10  * Using CompletionService to render page elements as they become available
11  *
12  * @author Brian Goetz and Tim Peierls
13  */
14 public abstract class Renderer {
15     private final ExecutorService executor;
16 
17     Renderer(ExecutorService executor) {
18         this.executor = executor;
19     }
20 
21     void renderPage(CharSequence source) {
22         final List<ImageInfo> info = scanForImageInfo(source);
23         CompletionService<ImageData> completionService =
24                 new ExecutorCompletionService<ImageData>(executor);
25         for (final ImageInfo imageInfo : info)
26             completionService.submit(new Callable<ImageData>() {
27                 public ImageData call() {
28                     return imageInfo.downloadImage();
29                 }
30             });
31 
32         renderText(source);
33 
34         try {
35             for (int t = 0, n = info.size(); t < n; t++) {
36                 Future<ImageData> f = completionService.take();
37                 ImageData imageData = f.get();
38                 renderImage(imageData);
39             }
40         } catch (InterruptedException e) {
41             Thread.currentThread().interrupt();
42         } catch (ExecutionException e) {
43             throw launderThrowable(e.getCause());
44         }
45     }
46 
47     interface ImageData {
48     }
49 
50     interface ImageInfo {
51         ImageData downloadImage();
52     }
53 
54     abstract void renderText(CharSequence s);
55 
56     abstract List<ImageInfo> scanForImageInfo(CharSequence s);
57 
58     abstract void renderImage(ImageData i);
59 
60 }

 

posted @ 2021-02-09 10:09  苏黎世湖畔  阅读(326)  评论(0编辑  收藏  举报