Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的异步开源工作流软件_Java_Asynchronous_Workflow_Pipeline - Fatal编程技术网

Java中的异步开源工作流软件

Java中的异步开源工作流软件,java,asynchronous,workflow,pipeline,Java,Asynchronous,Workflow,Pipeline,我有一个系统,有一系列的活动(大约40个)。每个活动要么调用一个服务,要么执行一些计算。这个系统是用Java编写的。目前,所有这些活动都是按顺序执行的,整个过程大约需要2-3秒。我正在尝试优化系统,并尝试减少延迟。我注意到有些活动具有数据依赖性,有些活动是独立的。我试图使这些活动并行运行,同时维护具有数据依赖性的活动序列。例如,假设活动“A”到“F”按以下顺序依次执行: A->B->C->D->E->F (Activities) 1 2 3 4

我有一个系统,有一系列的活动(大约40个)。每个活动要么调用一个服务,要么执行一些计算。这个系统是用Java编写的。目前,所有这些活动都是按顺序执行的,整个过程大约需要2-3秒。我正在尝试优化系统,并尝试减少延迟。我注意到有些活动具有数据依赖性,有些活动是独立的。我试图使这些活动并行运行,同时维护具有数据依赖性的活动序列。例如,假设活动“A”到“F”按以下顺序依次执行:

A->B->C->D->E->F  (Activities)  
1   2   3   4  5  6  (Time Units)  
假设A生成的数据由E使用,B生成的数据由F使用,其余活动不依赖于任何其他数据。我应该能够按照以下顺序并行运行这些活动,而不是按顺序运行这些活动-

A->E  
B->F  
C  
D  
1  2 (Time)  

因此,系统应该能够在2个时间单位内完成整个过程,而不是6个时间单位。是否有任何开源Java框架可用于处理此类工作流,并在数据可用时无缝执行活动?

答案取决于依赖关系图的拓扑结构。如果它可以拆分为独立的线性序列(如示例中所示),那么只需将每个序列表示为可运行序列,并使用各自的线程运行它,或者将它们提交到线程池

如果序列像这样分支:

A->B->C
   |
   ->D->E
然后首先运行序列ABC,然后从活动B运行DE

最复杂的情况是当一个活动依赖于两个或多个活动时:

A->B -> |
C  ->   |->D // needs both results from B and C
图中需要一个节点,用于收集结果,并在收集所有结果时启动新序列。如果使用线程,则可以将每个依赖项表示为阻塞队列,并使用
BlockingQueue.take()
方法让依赖活动首先从所有输入队列中读取。如果使用线程池,则可以:

  • 使用Java8
    CompletableFuture
    类及其方法
    runaftertwo
    (用于2个依赖项)或
    allOf
    (用于任意数量的依赖项)

  • 使用一些数据流库(作为作者,我推荐)

  • 自己实现加入节点,这没什么大不了的


答案取决于依赖图的拓扑结构。如果它可以拆分为独立的线性序列(如示例中所示),那么只需将每个序列表示为可运行序列,并使用各自的线程运行它,或者将它们提交到线程池

如果序列像这样分支:

A->B->C
   |
   ->D->E
然后首先运行序列ABC,然后从活动B运行DE

最复杂的情况是当一个活动依赖于两个或多个活动时:

A->B -> |
C  ->   |->D // needs both results from B and C
图中需要一个节点,用于收集结果,并在收集所有结果时启动新序列。如果使用线程,则可以将每个依赖项表示为阻塞队列,并使用
BlockingQueue.take()
方法让依赖活动首先从所有输入队列中读取。如果使用线程池,则可以:

  • 使用Java8
    CompletableFuture
    类及其方法
    runaftertwo
    (用于2个依赖项)或
    allOf
    (用于任意数量的依赖项)

  • 使用一些数据流库(作为作者,我推荐)

  • 自己实现加入节点,这没什么大不了的


    • 这是一个专门用于此目的的框架(称为),您可以参考和阅读有关此用例示例的文章。有关类似于用例的工作流,请参阅

      下面是如何使用Dexecutor

      DexecutorConfig<String, String> config = new DexecutorConfig<>(executorService, new TaskProvider());
      DefaultDexecutor<String, String> executor = new DefaultDexecutor<String, String>(config);
      
      executor.addDependency("A", "E");
      executor.addDependency("B", "F");
      executor.addIndependent("C");
      executor.addIndependent("D");
      
      executor.execute(ExecutionConfig.NON_TERMINATING);
      
      DexecutorConfig config=new DexecutorConfig(executorService,new TaskProvider());
      DefaultDexecutor executor=新的DefaultDexecutor(配置);
      遗嘱执行人。添加附属关系(“A”、“E”);
      遗嘱执行人。添加从属关系(“B”、“F”);
      执行人。额外独立(“C”);
      执行人。额外独立(“D”);
      executor.execute(ExecutionConfig.NON_终止);
      

      免责声明:我是此框架的所有者

      这是一个专门用于此目的的框架(称为),您可以参考和阅读有关此用例示例的Dzone文章。有关类似于用例的工作流,请参阅

      下面是如何使用Dexecutor

      DexecutorConfig<String, String> config = new DexecutorConfig<>(executorService, new TaskProvider());
      DefaultDexecutor<String, String> executor = new DefaultDexecutor<String, String>(config);
      
      executor.addDependency("A", "E");
      executor.addDependency("B", "F");
      executor.addIndependent("C");
      executor.addIndependent("D");
      
      executor.execute(ExecutionConfig.NON_TERMINATING);
      
      DexecutorConfig config=new DexecutorConfig(executorService,new TaskProvider());
      DefaultDexecutor executor=新的DefaultDexecutor(配置);
      遗嘱执行人。添加附属关系(“A”、“E”);
      遗嘱执行人。添加从属关系(“B”、“F”);
      执行人。额外独立(“C”);
      执行人。额外独立(“D”);
      executor.execute(ExecutionConfig.NON_终止);
      

      免责声明:我是此框架的所有者

      我认为这很难维护。工作流引擎应该是声明式的,而不是命令式的。在我看来,这很难维护。工作流引擎应该是声明式的,而不是命令式的。