以前看过一篇文章介绍JBPM流程并发的,也是通过fork节点,但是没有join节点直接拉到End节点,逻辑上可以实现,但是看起来让人感觉有点乱.当然了通过一个节点多个task也可以实现,可是流程图看起来总觉得别扭,那也就不是什么流程.言归正传,Token贯穿整个流程,一个Token可以有多个子Token,在fork和join中有多少走向,就会有多少子Token.那么我们可以不可以给Token添加子Token呢?答案是可以的,我们可以通过T构造函数Token(Token parent,String name)来创建一个子Token.问题又来了,什么时候创建token呢,通过试验在Fork节点是可以创建的,但是新建的Token会一直停留在fork节点上,需要手动Single下去.而在fork节点single的话会有异常,那就需要在fork和join之间拉一条transition,在这条transition来控制,在transition上的action创建Token,赋值对应的变量然后Single下去.下面介绍一下如何实现.
流程图
流程定义
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="" name="test">
<start-state name="开始节点">
<transition to="fork1"></transition>
</start-state>
<fork name="fork1">
<transition to="并发">
<action></action>
</transition>
<transition to="join1" name="control">
<action class="test.Controler"></action>
</transition>
</fork>
<task-node name="并发">
<task name="并发任务"></task>
<transition to="join1"></transition>
</task-node>
<join name="join1">
<transition to="结束"></transition>
</join>
<end-state name="结束"></end-state>
</process-definition>
流程的目的是,在流程开始时给流程变量departments赋值,不同部门用','隔开,可每个部门都要走'并发'那条线,有多少部门就并发几条,每一条对应一个Token,每个Token中有同名变量dept,当然对不同的部门这个值不同,这里通过ContextInstance的createVariable(name,value,token)方法来实现,处理task的时候也是通过对应的方法得到对应的值.下面是action 的handler类 test.Controler的代码,
package test;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
public class Controler implements ActionHandler {
public void execute(ExecutionContext arg0) throws Exception {
ProcessInstance pi=arg0.getProcessInstance();
ContextInstance ci=pi.getContextInstance();
String deparments=(String) ci.getVariable("departments");
String[] deptArry=deparments.split(",");
Token root=pi.getRootToken();
//默认的token
Token degaultToken=root.getChild("1");
ci.createVariable("dept", deptArry[0], degaultToken);
//其他部门分别创建对应的token,并分别对变量dept赋值
for(int i=1;i<deptArry.length;i++){
Token newToken=new Token(root,deptArry[i]);
ci.createVariable("dept", deptArry[i], newToken);
newToken.signal();
}
}
}
测试结果代码为
package test;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;
import org.jbpm.taskmgmt.exe.TaskInstance;
import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
public class Test {
public static void main(String[] args) {
JbpmContext jc = JbpmConfiguration.getInstance().createJbpmContext();
ProcessDefinition pd = jc.getGraphSession()
.findLatestProcessDefinition("test");
ProcessInstance pi = pd.createProcessInstance();
System.out.println("新流程开始成功!!");
Token root = pi.getRootToken();
ContextInstance ci = pi.getContextInstance();
//把部门参数加入流程当中
ci.createVariable("departments", "dept1,dept2,dept3");
root.signal();
TaskMgmtInstance tmi = pi.getTaskMgmtInstance();
Collection c = tmi.getTaskInstances();
Iterator iter = c.iterator();
System.out.println("rootToken:" + root.getNode());
priintTokenChhilds(root);
while (iter.hasNext()) {
TaskInstance ti = (TaskInstance) iter.next();
Token token = ti.getToken();
String dept = (String) ci.getVariable("dept", token);
ti.end();
System.out.println("部门" + dept + "的task'" + ti.getName() + "'结束");
System.out.println("rootToken:" + root.getNode());
priintTokenChhilds(root);
}
jc.close();
}
public static void priintTokenChhilds(Token token) {
Map childs = token.getChildren();
Iterator it = childs.keySet().iterator();
while (it.hasNext()) {
Token child = (Token) childs.get(it.next());
System.out.println(child.getFullName() + ":" + child.getNode());
}
}
}
测试结果
新流程开始成功!!
rootToken:Fork(fork1)
/dept2:TaskNode(并发)
/dept3:TaskNode(并发)
/control:Join(join1)
/1:TaskNode(并发)
部门dept1的task'并发任务'结束
rootToken:Fork(fork1)
/dept2:TaskNode(并发)
/dept3:TaskNode(并发)
/control:Join(join1)
/1:Join(join1)
部门dept2的task'并发任务'结束
rootToken:Fork(fork1)
/dept2:Join(join1)
/dept3:TaskNode(并发)
/control:Join(join1)
/1:Join(join1)
部门dept3的task'并发任务'结束
rootToken:EndState(结束)
/dept2:Join(join1)
/dept3:Join(join1)
/control:Join(join1)
/1:Join(join1)
/1节点是流程默认的子Token,代表dept1那条线.
可见所有的Token结束之后,rootToken就到达了结束节点,这是对于在并发之前已经知道并发流程个数的实现方法,对于在流程中不知道并发的条数实现方式类似,只是control那那条控制线改成task节点来实现并发控制就可以.这是这个节点要手动结束
分享到:
相关推荐
#### 一、并发编程与Fork-Join框架的引入 在现代计算环境中,多核处理器已经成为标配,这为软件开发者提供了利用硬件并行性的巨大潜力。然而,传统的并发编程模型,如基于线程的编程,虽然直观但存在诸多挑战,包括...
Java并发Fork-Join框架原理 Java并发Fork-Join框架原理是Java7中提供的一种并行执行任务的框架,旨在提高程序的执行效率和性能。该框架的核心思想是将大任务分割成若干个小任务,并将其分配给不同的线程执行,以...
Go-Golang版的Fork-Join框架是一种在Golang中实现的并发编程模型,灵感来源于Java的ForkJoin框架。这个框架的核心理念是通过将大任务分解为小任务,然后并行执行这些小任务,最后合并结果,以提高计算效率。在Golang...
赠送jar包:eclipse-collections-forkjoin-7.1.2.jar; 赠送原API文档:eclipse-collections-forkjoin-7.1.2-javadoc.jar; 赠送源代码:eclipse-collections-forkjoin-7.1.2-sources.jar; 赠送Maven依赖信息文件:...
fork/join框架是ExecutorService接口的一个实现,可以帮助开发人员充分利用多核处理器的优势,编写出并行执行的程序,提高应用程序的性能;设计的目的是为了处理那些可以被递归拆分的任务。
Harrison 在 IFIP Performance 2015 接受的论文“Beyond the Mean in Fork-Join Queues: Efficient Approximation for Response-Time Tails”中提出的近似方法。 文件 main_example.m 中提供了如何使用脚本的示例,...
赠送jar包:eclipse-collections-forkjoin-7.1.2.jar; 赠送原API文档:eclipse-collections-forkjoin-7.1.2-javadoc.jar; 赠送源代码:eclipse-collections-forkjoin-7.1.2-sources.jar; 赠送Maven依赖信息文件:...
在Java并发编程中,Fork/Join框架是一个强大的工具,尤其在处理大量数据时能显著提升性能。这个框架从Java 7开始引入,是ExecutorService的一个实现,它基于分而治之的策略,将大任务分解成多个小任务,然后并行地...
在jbpm中,"fork & join"机制是实现并行处理和流程控制的关键概念,尤其在处理会签(多个审批人同时参与审批)等场景时显得尤为重要。 "fork"在jbpm中指的是流程分支,当流程到达一个fork节点时,流程会分裂为多个...
Fork/Join框架是Java并发库中的一部分,自Java 7开始引入,它为开发者提供了一种高效的处理大规模计算任务的方法。这个框架基于分治策略,将大任务分解成若干小任务,然后并行执行这些小任务,最后再将结果合并。...
Fork-Join实时任务图模型(FJRT模型)是该领域内的一项重要研究,它通过结合分支代码建模和任务内并行结构建模,扩展了基于有向图的任务模型,引入了任务分叉(forking)和合并(joining)的概念。 在研究实时系统...
在实际操作中,开发者可以通过JBPM的图形界面或XML配置文件来实现`Fork`和`Join`的布局,以满足业务需求。 为了更好地理解和应用这些概念,可以参考提供的博文链接(https://dolphin-ygj.iteye.com/blog/67860),...
`simple-fork-join`项目提供的示例代码可以帮助初学者理解如何在Java中使用ForkJoin框架来编写高效的并行计算程序。通过分析和实践这个项目,开发者可以深入掌握并行编程的核心概念,提升软件性能。
叉连接一个窃取fork-join并行性库的工作。 受博客文章的启发,并通过硕士论文。 托管在存储库托管的图书馆文档开发该库的目的是为了满足三种类型的算法的需求,这些算法都非常适合fork-join并行性。减少风格减少样式...
fork-rest-dataware-master
标题“Fork/Join例子”暗示我们将探讨一个具体的示例,展示如何使用这个框架来解决问题。通常,这样的例子会涵盖创建自定义的`RecursiveTask`或`RecursiveAction`类,以及如何使用`ForkJoinPool`来执行它们。 描述...
在Java编程中,线程池和并发任务执行是常见的方式,但在某些场景下,我们可以利用JDK的ForkJoin框架来构建更加高效和易用的并发组件。ForkJoin框架自Java 7引入,它为处理大型任务提供了一种分解成多个子任务并行...
ForkJoin并发框架是Java 7引入的一种高效并行计算框架,它基于分而治之(Divide and Conquer)的策略,适用于处理大量可分割的任务。这个框架的核心类是`ForkJoinPool`和`ForkJoinTask`,它们为开发者提供了创建和...
jBPM2 版本中,流程图和JBPM API 是核心组成部分,帮助开发者实现复杂的业务流程自动化。 ### 1. jBPM-jBDL 相关概念 jBPM-jBDL(jBPM Business Definition Language)是一种用来定义业务流程的语言,基于有向图...