• 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

    这样整个功能就很清晰了。

  • 相关阅读:
    nginx 配置上传文件大小限制
    linux大文件截取某个日期后面的所有内容
    软件架构笔记 五
    软件架构笔记 四
    软甲架构笔记 三
    软件架构笔记 二
    软件架构笔记 一
    c# 生成的没用文件
    c# 两个软件传参
    c# 四则运算出错
  • 原文地址:https://www.cnblogs.com/yipihema/p/5549111.html
Copyright © 2020-2023  润新知