京东任务编排框架asyncTool源码初探

京东的一个框架,可以像promise一样 支持多线程顺序执行,依赖执行 看了下文件规模,核心类就几个非常适合我哈哈哈哈。让我们来看看有啥神奇的地方吧

我们也可以从test模块中看到,很贴心的给我们准备了样例,从包名可以推出使用方法

  • 依赖
  • 新的依赖
  • 并行任务
  • 串行任务

进入 TestSequential 类,是怎么运行的,从以下代码可看出核心类是Iworker、Icallback、WorkerWrapper

public class TestSequential {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        SeqWorker w = new SeqWorker();
        SeqWorker1 w1 = new SeqWorker1();
        SeqWorker2 w2 = new SeqWorker2();

        //顺序0-1-2
        WorkerWrapper<String, String> workerWrapper2 =  new WorkerWrapper.Builder<String, String>()
                .worker(w2)
                .callback(w2)
                .param("2")
                .build();

        WorkerWrapper<String, String> workerWrapper1 =  new WorkerWrapper.Builder<String, String>()
                .worker(w1)
                .callback(w1)
                .param("1")
                .next(workerWrapper2)
                .build();

        WorkerWrapper<String, String> workerWrapper =  new WorkerWrapper.Builder<String, String>()
                .worker(w)
                .callback(w)
                .param("0")
                .next(workerWrapper1)
                .build();

        testGroupTimeout(workerWrapper);
    
        }
        private static void testGroupTimeout(WorkerWrapper<String, String> workerWrapper) throws ExecutionException, InterruptedException {
            long now = SystemClock.now();
            System.out.println("begin-" + now);
        
            Async.beginWork(2500, workerWrapper);
        
            System.out.println("end-" + SystemClock.now());
            System.err.println("cost-" + (SystemClock.now() - now));
        
            Async.shutDown();
        }
    }
  1. 定义callback类,实现ICallback接口重写result方法
  2. 定义work类,实现Iworker接口重写,重写action方法
  3. 定义WorkerWrapper,build模式将work、callback、入参传入组装。可以指定next为其他的WorkerWrapper,形成链条,供串行运行
  4. 使用Async.beginWork(2500, workerWrapper);启动, Async.shutDown()来结束异步线程。

整个系统的入口就在Async#beginWork方法上了

public static boolean beginWork(long timeout, ThreadPoolExecutor pool, List<WorkerWrapper> workerWrappers) throws ExecutionException, InterruptedException {
    if(workerWrappers == null || workerWrappers.size() == 0) {
        return false;
    }
    //定义一个map,存放所有的wrapper,key为wrapper的唯一id,value是该wrapper,可以从value中获取wrapper的result
    Map<String, WorkerWrapper> forParamUseWrappers = new ConcurrentHashMap<>();
    // 核心实现使用CompletableFuture
    CompletableFuture[] futures = new CompletableFuture[workerWrappers.size()];
    for (int i = 0; i < workerWrappers.size(); i++) {
        WorkerWrapper wrapper = workerWrappers.get(i);
        // 追溯源码时还在想为啥把pool一层层往work方法里传,原来是个CompletableFuture#runAsync方法使用的。真是精妙
        futures[i] = CompletableFuture.runAsync(() -> wrapper.work(pool, timeout, forParamUseWrappers), pool);
    }
    try {
        CompletableFuture.allOf(futures).get(timeout, TimeUnit.MILLISECONDS);
        return true;
    } catch (TimeoutException e) {
        Set<WorkerWrapper> set = new HashSet<>();
        totalWorkers(workerWrappers, set);
        for (WorkerWrapper wrapper : set) {
            wrapper.stopNow();
        }
        return false;
    }
}

其中这个pool是一个静态变量,可以根据自己的需求来调整线程数量。

public static final ThreadPoolExecutor COMMON_POOL =
        new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors() * 2, 1024,
                15L, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(),
                (ThreadFactory) Thread::new);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章