OrderedExecutor

与JAVA Executor的区别

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

源码分析

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

private static final class OrderedExecutor implements Executor {
    private final LinkedList 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队列,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又独占了这个线程。

你可能感兴趣的:(OrderedExecutor)