美文网首页Vert.x
OrderedExecutor

OrderedExecutor

作者: 沧行 | 来源:发表于2016-11-20 16:50 被阅读0次

    与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又独占了这个线程。

    相关文章

      网友评论

        本文标题:OrderedExecutor

        本文链接:https://www.haomeiwen.com/subject/mqlypttx.html