OrderedExecutor

与JAVA Executor的区别

vertx框架提供了OrderedExecutor的实现,其能保证提交的任务按照严格的提交顺序执行,在idk Executor的线程池中,多线程情况下可能无法保证提交的任务顺序执行。

源码分析

下面看下vertx的OrderedExecutor实现,其源码并不长,如下:

private static final class OrderedExecutor implements Executor {
    private final LinkedList<Runnable> tasks = new LinkedList<>();
    private boolean running;
    private final Executor parent;
    private final Runnable runner;
    public OrderedExecutor(Executor parent) {
        this.parent = parent;
        runner = () -> {
            for (; ; ) {
                final Runnable task;
                synchronized (tasks) {
                      task = tasks.poll();
                      if (task == null) {
                        running = false;
                        return;
                      }
                }
                try {
                      task.run();
                } catch (Throwable t) {
                      log.error("Caught unexpected Throwable", t);
                }
            }
        };
    }

    public void execute(Runnable command) {
        synchronized (tasks) {
            tasks.add(command);
            if (!running) {
                running = true;
                parent.execute(runner);
            }
        }
    }
}  

OrderedExecutor包含4个成员变量,tasks(LinkedList<Runnable>)是runnable队列,parent(Executor)是真正执行runnable的执行器,runner(Runnable)是顺序执行器要执行的任务,running为运行状态标志。

首先分析runner,其运行的任务是个循环任务,只有当tasks中没有要执行的任务了才退出。其逻辑很简单,就是循环从tasks中获取任务并执行。

再看execute方法,其逻辑也很简单,就是向tasks中添加runnable,如果runner没有执行,那么就将其提交给parent线程池运行起来。

因为runner是按顺序从tasks中取任务执行的,因此保证了该OrderedExecutor execute的任务是按顺序执行的。

再介绍下创建OrderedExecutor的工厂类OrderedExecutorFactory,其代码如下:

public class OrderedExecutorFactory {

    static final Logger log = LoggerFactory.getLogger(OrderedExecutorFactory.class);

    private final Executor parent;

    public OrderedExecutorFactory(Executor parent) {
        this.parent = parent;
    }

    public OrderedExecutor getExecutor() {
        return new OrderedExecutor(parent);
    }
}

其代码更简单,就是传入一个线程池执行器parent,每次创建OrderedExecutor要共享这个parent执行器。

下面分析下OrderedExecutor和Executor的关系,虽然OrderedExecutor实现了Executor,但它们并不是简单的平行对等关系,1个Executor可以对应多个OrderedExecutor。

1个Executor相当于1个线程池,但每个OrderedExecutor在运行状态会独占1个线程,因为在把runner提交给parent执行时,parent会选出1个空闲线程执行该runner,而该runner是个循环任务,会独占这个线程。

OrderedExecutor通过1个runner任务处理所有提交到该OrderedExecutor的runnable,当处理完tasks中所有任务后就把线程归还给parent(Executor),当下次有新的runnable提交进来时再把runner提交给parent(Executor),parent再取出1个空闲线程运行runner,这个runner又独占了这个线程。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,120评论 19 139
  • 一.线程安全性 线程安全是建立在对于对象状态访问操作进行管理,特别是对共享的与可变的状态的访问 解释下上面的话: ...
    黄大大吃不胖阅读 4,359评论 0 3
  • 那些外卖、家政、美业等只想通过线上引流(一维)、线下服务(二维)、门店加盟(三维的轻模式,重不了多少,至多只能算是...
    张书乐阅读 4,650评论 0 48
  • 2017年4月25号,早上六点十七分,上海虹桥站,天色还有点朦胧,出来有点凉,踏上了回家的路。 靠窗而坐,凝视着远...
    风中的女子阅读 1,364评论 0 3
  • 可惜不是你
    言持阅读 1,846评论 0 2

友情链接更多精彩内容