﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-jbpm-随笔分类-jbpm深入研究</title><link>http://www.blogjava.net/jbpm/category/25749.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 12 Sep 2007 01:02:00 GMT</lastBuildDate><pubDate>Wed, 12 Sep 2007 01:02:00 GMT</pubDate><ttl>60</ttl><item><title>jbpm并发的子流程的解决方案与探讨</title><link>http://www.blogjava.net/jbpm/archive/2007/09/11/144331.html</link><dc:creator>jbpm</dc:creator><author>jbpm</author><pubDate>Tue, 11 Sep 2007 09:48:00 GMT</pubDate><guid>http://www.blogjava.net/jbpm/archive/2007/09/11/144331.html</guid><wfw:comment>http://www.blogjava.net/jbpm/comments/144331.html</wfw:comment><comments>http://www.blogjava.net/jbpm/archive/2007/09/11/144331.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jbpm/comments/commentRss/144331.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jbpm/services/trackbacks/144331.html</trackback:ping><description><![CDATA[<br />
作者：&nbsp;<a href="http://jeffreyhsu.javaeye.com/"><font color="#000000">JeffreyHsu</font></a>
<p><font size="4"><br />
尽管jbpm非常强大，是目前最适合商业化的开源工作流引擎，可以开发出复杂的流程，但是特别遗憾的是并不支持并发子流程（multiple-subprocess） <br />
有一次我需要做一个复杂的流程，主流程里要求同时启动多个并发执行的子流程，并且子流程的数目和启动的时间都不确定，当所有子流程都结束以后，主流程才继续执行。我们知道jbpm里有子流程的设定，有专门的节点ProcessState来处理，但是后来发现无论如何也实现不了多子流程并发执行，后来看其源码知道因为subprocess是作为ProcessState的一个属性，也就是说ProcessState只能包含一个subprocess的定义，并且最重要的是processInstance.getRootToken()和子流程相关的只有createSubProcessInstance, getSubProcessInstance, setSubProcessInstance三个方法，这意味着主流程的rootToken只能设置一个子流程，jbpm并不直接支持多子流程。 <br />
那么我们就必须用一个变通的方法来实现，&#8220;并发&#8221;很自然的让我们想到了fork，但是这里的fork不能搭配join来使用，具体原因，将在后面讨论。 <br />
下面先给出流程图： <br />
</font><img alt="" src="http://jeffreyhsu.javaeye.com/upload/picture/pic/179/5c9ac511-8a90-43de-9202-cdf0a57b659e.jpg" border="0" /></p>
<p><font size="4">state节点用来启动子流程（实际应用可以换成Task-Node），state进入fork后同时进入两个分支，一条去启动子流程，另一条回到自己，这样表面看来state没有动，而同时你又可以启动第2个，第3个&#8230;&#8230;子流程，需要注意的是第2条子流程和第1个子流程并不处于同一级上，而比第一个子流程低一级，具体请看后面一张图就明白了，分解后的： <br />
</font><img alt="" src="http://jeffreyhsu.javaeye.com/upload/picture/pic/180/876117a3-9aab-4ece-8d66-6fe74bfbb4dc.jpg" border="0" /></p>
<p><font size="4">从图中我们可以看到后一个子流程的整棵树是前一个子流程的兄弟，但是在业务级上是并发的效果，已经实现我们前面的需求。</font></p>
<p><font size="4">现在来说说为什么不能用join而直接用end，因为会产生一个问题，state3和sub process 2都到达了join以后，state2下面的fork就结束了，就会立刻越过join到达end，而sub process 1即使执行完毕到达了join却仍然在傻傻等待着他的兄弟分支也到达join（而实际上它已经自跑到end去了）一同结束，这样sub process 1就会永远停在join动弹不得，业务无法进行。</font></p>
<p><font size="4">这是我的一个解决方案，但还有一个问题，虽然全部的子流程都能结束，主流程也能结束，但因为没有join，主流程的rootToken仍然停留在fork节点上。目前我尚不知如何解决，希望各位大家能提出其他更好的解决办法。 <br />
初学jbpm，水平有限，有不当之处还请高手斧正</font></p>
<p><font size="4">最后附上demo代码供参考： <br />
</font></p>
<div class="code_title"><font size="4">代码</font></div>
<div class="code_div">
<div class="bar"><font size="4"></font></div>
<div></div>
</div>
<font size="4">
<ol class="dp-xml">
    <li class="alt"><font size="3"><span><span>&nbsp;&nbsp;</span></span> </font>
    <li class=""><font size="3"><span>import&nbsp;static&nbsp;org.junit.Assert.*; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>import&nbsp;org.jbpm.graph.def.ProcessDefinition; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>import&nbsp;org.jbpm.graph.exe.ProcessInstance; &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>import&nbsp;org.jbpm.graph.exe.Token; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>import&nbsp;org.jbpm.graph.node.ProcessState; &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>import&nbsp;org.junit.Before; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>import&nbsp;org.junit.Test; &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>public&nbsp;class&nbsp;MultiProcessTest&nbsp;{ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ProcessDefinition&nbsp;superProcessDefinition; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ProcessDefinition&nbsp;subProcessDefinition; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;@Before &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;setUp()&nbsp;throws&nbsp;Exception&nbsp;{ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">superProcessDefinition</span><span>&nbsp;=&nbsp;ProcessDefinition.parseXmlString( &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"</span><span class="tag">&lt;</span><span class="tag-name">process-definition</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'super'</span><span class="tag">&gt;</span><span>"&nbsp;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">start-state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'start'</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'state'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">start-state</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </span></font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'state'</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'create&nbsp;sub'</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'fork'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'end'</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'end'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">state</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </span></font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">fork</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'fork'</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'back'</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'state'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'go&nbsp;to&nbsp;sub'</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'sub&nbsp;process'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">fork</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </span></font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">process-state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'sub&nbsp;process'</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">sub-process</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'sub'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'end'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">process-state</span><span class="tag">&gt;</span></span></font><span><font size="3">"&nbsp;+</font> &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</font></span><font size="3"><span class="tag">&lt;</span><span class="tag-name">end-state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'end'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"</span><span class="tag"><span class="tag-name">process-definition</span><span class="tag">&gt;</span><span>"); &nbsp;&nbsp;</span> </span></font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="attribute">subProcessDefinition</span><span>&nbsp;=&nbsp;ProcessDefinition.parseXmlString( &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"</span><span class="tag">&lt;</span><span class="tag-name">process-definition</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'sub'</span><span class="tag">&gt;</span><span>"&nbsp;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">start-state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'start'</span><span class="tag">&gt;</span><span>"&nbsp;&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'wait'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">start-state</span><span class="tag">&gt;</span><span>"&nbsp;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </span></font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'wait'</span><span class="tag">&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">transition</span><span>&nbsp;</span><span class="attribute">to</span><span>=</span><span class="attribute-value">'end'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag"><span class="tag-name">state</span><span class="tag">&gt;</span><span>"&nbsp;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </span></font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"&nbsp;&nbsp;</span><span class="tag">&lt;</span><span class="tag-name">end-state</span><span>&nbsp;</span><span class="attribute">name</span><span>=</span><span class="attribute-value">'end'</span><span>&nbsp;</span><span class="tag">/&gt;</span><span>"&nbsp;+ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"</span><span class="tag"><span class="tag-name">process-definition</span><span class="tag">&gt;</span><span>"); &nbsp;&nbsp;</span> </span></font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessState&nbsp;</span><span class="attribute">processState</span><span>&nbsp;=&nbsp;(ProcessState)&nbsp;superProcessDefinition &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getNode("sub&nbsp;process"); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processState.setSubProcessDefinition(subProcessDefinition); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;@Test &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;testMultiProcesses()&nbsp;{ &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessInstance&nbsp;</span><span class="attribute">pi</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">new</span><span>&nbsp;ProcessInstance(superProcessDefinition); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">&nbsp;&nbsp;//&nbsp;启动一个主流程 &nbsp;&nbsp;</font></span><font size="3"> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pi.signal(); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals("state",&nbsp;pi.getRootToken().getNode().getName()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;进入分支，此处将进入子流程 &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pi.signal("create&nbsp;sub"); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;主流程token将停留在fork节点上 &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals("fork",&nbsp;pi.getRootToken().getNode().getName()); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;fork分为两支，其中一支的节点停留在ProcessState上 &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Token&nbsp;</span><span class="attribute">subProcessToken1</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">pi</span><span>.getRootToken().getChild("go&nbsp;to&nbsp;sub"); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessInstance&nbsp;</span><span class="attribute">subPi1</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">subProcessToken1</span><span>.getSubProcessInstance(); &nbsp;&nbsp;</span> </font>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">&nbsp;assertEquals("wait",&nbsp;subPi1.getRootToken().getNode().getName()); &nbsp;&nbsp;</font></span><font size="3"> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;另一支返回了state节点，实际上并没有返回，这个state节点不同于先前的state，它们并不在同一个path中 &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Token&nbsp;</span><span class="attribute">stateToken1</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">pi</span><span>.getRootToken().getChild("back"); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals("state",&nbsp;stateToken1.getNode().getName()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </font>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">&nbsp;&nbsp;&nbsp;//&nbsp;再次进入fork，启动第二个子流程 &nbsp;&nbsp;</font></span><font size="3"> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stateToken1.signal("create&nbsp;sub"); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessInstance&nbsp;</span><span class="attribute">subPi2</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">stateToken1</span><span>.getChild("go&nbsp;to&nbsp;sub") &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.getSubProcessInstance(); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;虽然都是子流程，但它们并不相同，在逻辑上是属于并发的无关系的子流程 &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFalse(subPi1.equals(subPi2)); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;结束第二个子流程 &nbsp;&nbsp;</span> </font>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">subPi2.signal(); &nbsp;&nbsp;</font></span><font size="3"> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(subPi2.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFalse(pi.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;结束第一个子流程，但主流程仍未结束 &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subPi1.signal(); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(subPi1.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFalse(pi.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;结束第二个子流程中的state，第一子流程的back分支结束，从而主流程也结束 &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Token&nbsp;</span><span class="attribute">stateToken2</span><span>&nbsp;=&nbsp;</span><span class="attribute-value">stateToken1</span><span>.getChild("back"); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals("state",&nbsp;stateToken2.getNode().getName()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFalse(stateToken1.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertFalse(pi.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stateToken2.signal("end"); &nbsp;&nbsp;</span> </font>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">&nbsp;&nbsp;&nbsp;assertTrue(stateToken1.hasEnded()); &nbsp;&nbsp;</font></span><font size="3"> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(subPi1.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(pi.getRootToken().getChild("back").hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(pi.getRootToken().getChild("go&nbsp;to&nbsp;sub").hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;主流程结束了 &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(pi.hasEnded()); &nbsp;&nbsp;</span> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;虽然主流程已经结束了，但是因为子流程没有join，所以其rootToken仍然停留在fork上 &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals("fork",&nbsp;pi.getRootToken().getNode().getName()); &nbsp;&nbsp;</span> </font>
    <li class=""><span><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;第二个子流程到达的end和主流程中的end并不是同一个节点</font> &nbsp;&nbsp;</span>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font size="3">&nbsp;&nbsp;&nbsp;assertTrue(!pi.getRootToken().getNode().equals(stateToken2.getNode())); &nbsp;&nbsp;</font></span><font size="3"> </font>
    <li class=""><font size="3"><span>&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;</span> </font>
    <li class="alt"><font size="3"><span>} &nbsp;&nbsp;</span> </font></li>
</ol>
</font>
<img src ="http://www.blogjava.net/jbpm/aggbug/144331.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jbpm/" target="_blank">jbpm</a> 2007-09-11 17:48 <a href="http://www.blogjava.net/jbpm/archive/2007/09/11/144331.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>