如何在Java中实现类似DAG的调度器?

如何在Java中实现类似DAG的调度器?,java,Java,我想用Java实现一个简单的类似DAG的调度器(无需结果),如下图所示: 我可以简单地使用手动代码来实现这一点: ExecutorService executor = Executors.newCachedThreadPool(); Future<?> futureA = executor.submit(new Task("A")); Future<?> futureC = executor.submit(new Task("C")); futureA.get(); F

我想用Java实现一个简单的类似DAG的调度器(无需结果),如下图所示:

我可以简单地使用手动代码来实现这一点:

ExecutorService executor = Executors.newCachedThreadPool();
Future<?> futureA = executor.submit(new Task("A"));
Future<?> futureC = executor.submit(new Task("C"));
futureA.get();
Future<?> futureB = executor.submit(new Task("B"));
futureB.get();
futureC.get();
Future<?> futureD = executor.submit(new Task("D"));
futureD.get();
实际上我已经实现了一个简单的:

但是我需要每100毫秒迭代一次所有的任务,看看哪个任务可以提交。在这个实现中也没有异常检查

我还检查了番石榴酱的未来上市,但我不知道如何正确使用它


任何关于如何实现DAG的建议,或推荐一个现有的开源调度程序,我们都将不胜感激。

您所寻找的内容可以使用google的guava库及其未来的可登录界面来完成。ListenableFutures允许您拥有复杂的异步操作链。在使用allAsList方法完成任务B和C后,您应该实现一个可侦听的future来执行任务D

可上市期货的文档:

关于可上市期货的教程:

使用allAsList、chain和transform方法的示例: Dexecutor(免责声明:我是所有者)是您正在查找的库,下面是一个示例

public class WorkFlowManager {

    private final Dexecutor<String, Boolean> dexecutor;

    public WorkFlowManager(ExecutorService executorService) {
        this.dexecutor = buildDexecutor(executorService);

        buildGraph();
    }

    private Dexecutor<String, Boolean> buildDexecutor(final ExecutorService executorService) {
        DexecutorConfig<String, Boolean> config = new DexecutorConfig<>(executorService, new WorkFlowTaskProvider());
        return new DefaultDexecutor<>(config);
    }

    private void buildGraph() {
        this.dexecutor.addDependency(TaskOne.NAME, TaskTwo.NAME);
        this.dexecutor.addDependency(TaskTwo.NAME, TaskThree.NAME);
        this.dexecutor.addDependency(TaskTwo.NAME, TaskFour.NAME);
        this.dexecutor.addDependency(TaskTwo.NAME, TaskFive.NAME);
        this.dexecutor.addDependency(TaskFive.NAME, TaskSix.NAME);
        this.dexecutor.addAsDependentOnAllLeafNodes(TaskSeven.NAME);
    }

    public void execute() {
        this.dexecutor.execute(ExecutionConfig.TERMINATING);
    }
}
公共类工作流管理器{
私用最终Dexecutor Dexecutor;
公共工作流管理器(ExecutorService ExecutorService){
this.dexecutor=buildDexecutor(executorService);
buildGraph();
}
专用Dexecutor buildDexecutor(最终执行器服务执行器服务){
DexecutorConfig config=new DexecutorConfig(executorService,new WorkFlowTaskProvider());
返回新的DefaultDexecutor(配置);
}
私有void buildGraph(){
this.dexecutor.addDependency(TaskOne.NAME,TaskTwo.NAME);
this.dexecutor.addDependency(TaskTwo.NAME,TaskThree.NAME);
this.dexecutor.addDependency(TaskTwo.NAME,TaskFour.NAME);
this.dexecutor.addDependency(TaskTwo.NAME,TaskFive.NAME);
this.dexecutor.addDependency(TaskFive.NAME,TaskSix.NAME);
this.dexecutor.addAsDependentOnAllLeafNodes(TaskSeven.NAME);
}
public void execute(){
this.dexecutor.execute(ExecutionConfig.TERMINATING);
}
}
它将构建下面的图表,并相应地执行。

有关更多详细信息,请参阅

为什么使用Dexecutor

  • 超轻重量
  • 超快
  • 支持立即/计划重试逻辑
  • 支持非终止行为
  • 有条件地跳过任务执行
  • 良好的测试覆盖率,确保您免受伤害
  • 可在maven central购买
  • 大量的文件
  • 支持分布式执行(Ignite、Hazelcast、Infinispan)
有用链接


另一个可能的方向是提供一个接口,用于使用类似同步的习惯用法编写和定义异步图形流

作为一个简短的示例,一个复杂的图形流如下所示:

可通过以下方式简单实现:

Result<String> aResult = produceFutureOf(String.class).byExecuting(() -> executeA());
Result<String> bResult = ifResult(aResult).succeed().produceFutureOf(String.class).byExecuting(a -> executeB(a));
Result<String> cResult = ifResult(aResult).succeed().produceFutureOf(String.class).byExecuting(a -> executeC(a));
Result<String> eResult = ifResult(aResult).succeed().produceFutureOf(String.class).byExecuting(a -> executeE(a));
Result<String> dResult = ifResults(bResult, cResult).succeed().produceFutureOf(String.class).byExecuting((b, c) -> executeD(b, c));
Result<String> fResult = ifResult(eResult).succeed().produceFutureOf(String.class).byExecuting(e -> executeF(e));
Result<String> gResult = ifResult(fResult).succeed().produceFutureOf(String.class).byExecuting(f -> executeG(f));
return ifResults(dResult, gResult).succeed().produceFutureOf(String.class).byExecuting((d, g) -> executeH(d, g));
Result aResult=produceFutureOf(String.class).byExecuting(()->executeA());
Result bResult=ifResult(aResult).succeed().produceFutureOf(String.class).byExecuting(a->executeB(a));
Result cResult=ifResult(aResult).success().produceFutureOf(String.class).byExecuting(a->executeC(a));
Result-eResult=ifResult(aResult).succeed().produceFutureOf(String.class).byExecuting(a->executeE(a));
Result dResult=ifResults(bResult,cResult).succeed().produceFutureOf(String.class).byExecuting((b,c)->executeD(b,c));
Result fResult=ifResult(eResult).succeed().produceFutureOf(String.class).byExecuting(e->executeF(e));
Result gResult=ifResult(fResult).succeed().produceFutureOf(String.class).byExecuting(f->executeG(f));
通过执行((d,g)->executeH(d,g)),返回ifResults(dResult,gResult).succeed().produceFutureOf(String.class);

更多信息请参见

我们可以使用Java8 CompletableFuture来解决您的问题,核心如下:

Container container = new Container();
container.addTask("A", new Task("A"));
container.addTask("B", new Task("B"), "A");
container.addTask("C", new Task("C"));
container.addTask("D", new Task("D"), "B", "C");
container.waitForCompletion();
for (Task dependedentTask : dependedentTasks) {
    // get dependedentFuture by dependedentTask,for example
    CompletableFuture dependedentFuture = futureMap.get(dependedentTask);
    dependedentFutures.add(dependedentFuture);
}
CompletableFuture.allOf(dependedentFutures).thenRunAsync(current task execute it's method)...

希望有人能编写代码。

I您只想同时运行任务
A
B
C
,然后等待它们完成,为什么不使用
invokeAll
@boristesspider
B
取决于
A
,可能会有更复杂的图形。这是一个非线性管道。查找管道模式,有几个java库实现了它。