博客
关于我
java中CompletionService的使用
阅读量:423 次
发布时间:2019-03-06

本文共 2874 字,大约阅读时间需要 9 分钟。

CompletionService的使用指南:Java中高效的任务执行管理

在Java编程中,处理多个任务的执行和结果管理是开发者常遇到的挑战。ExecutorService提供了一种简洁的方式来管理任务,但它在处理大量任务和结果管理方面仍有不足。为了更高效地解决这些问题,Java提供了CompletionService接口,这个接口结合了ExecutorService和BlockingQueue的功能,使得任务执行更加便捷和高效。以下将详细介绍CompletionService的使用方法。


ExecutorService的局限性

在使用ExecutorService时,开发者需要手动管理每个提交的Future任务。虽然ExecutorService提供了invokeAll方法来批量提交任务,但仍然需要保存每个Future的引用,并在需要的时候逐个查询结果。这种方法虽然可行,但在处理大量并发任务时会带来管理上的复杂性。


CompletionService的优势

CompletionService作为ExecutorService和BlockingQueue的结合体,提供了一种更高效的方式来管理任务和结果。它的主要优势在于:

  • 自动管理Future:通过CompletionService,Future的结果会自动存储在队列中,无需手动保存。
  • 简化结果获取:开发者可以通过take或poll方法直接从队列中获取任务结果,而无需逐个处理Future。
  • 更高效的资源管理:CompletionService能够更好地管理线程池和任务执行,减少资源浪费。

  • ExecutorCompletionService的实现

    CompletionService接口的主要实现是ExecutorCompletionService,它接受一个Executor作为参数。以下是ExecutorCompletionService的实现代码:

    public class ExecutorCompletionService implements CompletionService {    private final ExecutorService executor;    private final AbstractExecutorService aes;    private final LinkedBlockingQueue
    > completionQueue; 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<>(); } // 其他实现细节...}

    使用CompletionService进行任务提交和结果获取

    与ExecutorService不同,使用CompletionService时,开发者只需要提交任务,然后通过take或poll方法获取结果。以下是使用CompletionService的示例代码:

    public void useCompletionService() throws InterruptedException, ExecutionException {    ExecutorService executor = Executors.newFixedThreadPool(10);    CompletionService completionService = new ExecutorCompletionService(executor);    Callable
    callableTask = () -> { TimeUnit.MILLISECONDS.sleep(300); return "Task's execution"; }; for (int i = 0; i < 5; i++) { completionService.submit(callableTask); } for (int i = 0; i < 5; i++) { Future
    result = completionService.take(); System.out.println(result.get()); }}

    CompletionService的工作原理

    CompletionService内部通过以下方式工作:

  • 提交任务:当使用submit方法提交任务时,任务会被提交到ExecutorService的线程池中执行。
  • 存储结果:执行任务完成后,结果会被封装到Future对象中,并存储在内部的BlockingQueue中。
  • 取结果:开发者可以通过take方法(等待直到有结果可取)或poll方法(如果队列为空则返回null)来获取任务结果。

  • CompletionService的优点

  • 简化管理:CompletionService自动管理Future的存储和结果查询,减少了手动操作的复杂性。
  • 提高效率:通过自动化的结果存储和查询,开发者可以更高效地处理大量任务。
  • 良好的可扩展性:CompletionService能够与不同的ExecutorService实现兼容,适用于多种任务执行场景。

  • 使用 CompletionService 的注意事项

  • 线程安全:CompletionService的队列是线程安全的,但在多线程环境中使用时,仍需注意并发访问的管理。
  • 异常处理:在处理结果时,需要考虑可能的ExecutionException和InterruptedException等异常。
  • 性能优化:在高负载场景下,合理配置线程池大小和队列容量,可以提升性能。

  • 总结

    CompletionService通过将ExecutorService与BlockingQueue相结合,提供了一种更高效的任务执行和结果管理方式。它简化了Future的管理,减少了手动操作的复杂性,特别适用于处理大量并发任务的场景。在实际开发中,可以通过CompletionService来更好地优化代码结构,提升开发效率。

    转载地址:http://wenuz.baihongyu.com/

    你可能感兴趣的文章
    Openlayers高级交互(1/20): 控制功能综合展示(版权、坐标显示、放缩、比例尺、测量等)
    查看>>
    Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
    查看>>
    Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
    查看>>
    Openlayers高级交互(12/20):利用高德逆地理编码,点击位置,显示坐标和地址
    查看>>
    Openlayers高级交互(13/20):选择左右两部分的地图内容,横向卷帘
    查看>>
    Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
    查看>>
    Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
    查看>>
    Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
    查看>>
    Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
    查看>>
    Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
    查看>>
    Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
    查看>>
    Openlayers高级交互(2/20):清除所有图层的有效方法
    查看>>
    Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
    查看>>
    Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
    查看>>
    Openlayers高级交互(4/20):手绘多边形,导出KML文件,可以自定义name和style
    查看>>
    Openlayers高级交互(5/20):右键点击,获取该点下多个图层的feature信息
    查看>>
    Openlayers高级交互(6/20):绘制某点,判断它是否在一个电子围栏内
    查看>>
    Openlayers高级交互(7/20):点击某点弹出窗口,自动播放视频
    查看>>
    Openlayers高级交互(8/20):选取feature,平移feature
    查看>>
    Openlayers高级交互(9/20):编辑图形(放缩、平移、变形、旋转),停止编辑
    查看>>