前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CompletionService小技巧

CompletionService小技巧

作者头像
Allen Cheng
发布2018-09-10 11:31:40
8720
发布2018-09-10 11:31:40
举报
文章被收录于专栏:听Allen瞎扯淡听Allen瞎扯淡

在上一篇blogs中,我详细的解释了CompletionService的使用方法和ExecutorCompletionService的详细实现,这篇blogs中,我就介绍使用它的一个小技巧,算是对上一篇blogs的一个补完。在开始之前我们先回顾一下它的实现。

首先,在初始化ExecutorCompletionService的时候我们需要传入一个Executor,作为ExecutorCompletionService执行任务的容器。

public ExecutorCompletionService(Executor executor) { [......]}public ExecutorCompletionService(Executor executor, BlockingQueue<Future<V>> completionQueue) { [......]}

然后,调用submit方法,向它提交任务。submit方法会将我们提交的任务包装成一个QueueingFuture并提交给Executor来执行。

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; }

接着,QueueingFuture会在任务执行完成后把执行结果放到队列中。

private class QueueingFuture extends FutureTask<Void> { QueueingFuture(RunnableFuture<V> task) { super(task, null); this.task = task; } protected void done() { completionQueue.add(task); } private final Future<V> task;}

最后,我们通过take或者poll方法就能拿到任务执行的结果。

下面让我们设想一个场景,我需要从网络上下载几张图片和视频并最后把它们渲染到页面上去,由于下载图片和视频都比较耗时,所以我希望能以多线程的形式进行下载。但是由于资源有限,下载的并发度不能太大,所以需要限制线程池的并发线程大小。但如果将可用线程数平均分给下载图片和下载视频的线程池,当某线程池的所有任务执行完成后,另外一个线程池也无法获取到它所释放的资源。那怎么办呢?我们可以创建一个统一的线程池,然后把两个CompletionService绑定上去,让CompletionService作为一个句柄来使用。

final ExecutorService pool = Executors.newFixedThreadPool(5);final ExecutorCompletionService<Image> imageCompletionService = new ExecutorCompletionService<>(pool);for (final String site : imageSites) { completionService.submit(new Callable<Image>() { @Override public String call() throws Exception { return IOUtils.toString(new URL("http://" + site), StandardCharsets.UTF_8); } });}final ExecutorCompletionService<Video> vidoeCompletionService = new ExecutorCompletionService<>(pool);for (final String site : videoSites) { completionService.submit(new Callable<Video>() { @Override public String call() throws Exception { return IOUtils.toString(new URL("http://" + site), StandardCharsets.UTF_8); } });}List<Image> images = new ArrayList<>();for(int i = 0; i < topSites.size(); ++i) { final Future<String> future = completionService.take(); try { images.add(future.get()); } catch (ExecutionException e) { log.warn("Error while downloading", e.getCause()); }}List<Video> videos = new ArrayList<>();for(int i = 0; i < topSites.size(); ++i) { final Future<String> future = completionService.take(); try { videos.add(future.get()); } catch (ExecutionException e) { log.warn("Error while downloading", e.getCause()); }}// ... do process content

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016-08-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档