注 不同KieHelper肯定是不同的StatelessKiesession 但线程中试用则是唯一 只创建一次的不做修改的StatelessKiesession
请看如下代码:
package com.droolstest.dynamicRuleThread;
import com.droolstest.Person;
import com.droolstest.School;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;
import org.kie.internal.command.CommandFactory;
import org.kie.internal.conf.MultithreadEvaluationOption;
import org.kie.internal.utils.KieHelper;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class DrlStatelessHelpers {
private static int thread_num = 200;//线程数,设置同时并发线程数
private static int client_num = 10;//访问次数
/**
* 测试 并发下 使用
* 不同 KieHelper
* 不同StatelessKiesession无状态 注 不同KieHelper肯定是不同的StatelessKiesession 但线程中试用则是唯一 只创建一次的不做修改的StatelessKiesession
*/
/**
* 结论1:rule 名是能重复,这一点,符合kmodule.xml 规范要求 原因 虚拟文件在不同的虚拟目录中
* 结论2:rule与rule之间的Fact会相互作用 虽然在代码中 分别将Person和School insert到 两个不同的Kiesession中
* 但由于myRulefile1先执行,导致Fact对象发现变化 myRuleFile2规则无法满足条件
* 结论3:虽然StatelessKiesession是不同的,KieHelper是不同的,但只执行其中一个执行中的执行,受salience 影响
* 结论4:helper1.build(MultithreadEvaluationOption.YES).newKieSession();没有实际效果
* 结论5:有状态创建的时间比无状态创建的时间要长
* @param args
*/
public static void main(String[] args) {
//规则文件
String myRuleFile1 = "package rules " + "import com.droolstest.Person;" + "import com.droolstest.School;" +
"rule \"myRule1\" " +
" when " +
" $p:Person(name==\"张三\")" +
" $s:School(name==\"北大\")" +
" then " +
" $p.setName(\"李四\");" +
" $s.setName(\"清华\");" +
" update($p);" +
" update($s);" +
"end " +
"rule \"myRule2\" " +
" salience 10" +
" when " +
" $p:Person(name==\"李四\")" +
" $s:School(name==\"清华\")" +
" then " +
" System.out.println(\"规则myRuleFile1被调用\");" +
"end";
String myRuleFile2 = "package rules " + "import com.droolstest.Person;" + "import com.droolstest.School;" +
"rule \"myRule1\" " +
" when " +
" $p:Person(name==\"张三\")" +
" $s:School(name==\"北大\")" +
" then " +
" $p.setName(\"王王\");" +
" $s.setName(\"张大\");" +
" update($p);" +
" update($s);" +
"end " +
"rule \"myRule2\" " +
" when " +
" $p:Person(name==\"王王\")" +
" $s:School(name==\"张大\")" +
" then " +
" System.out.println(\"规则myRuleFile2调用\");" +
"end";
long start = System.currentTimeMillis();
KieHelper helper1 = new KieHelper();
KieHelper helper2 = new KieHelper();
long end = System.currentTimeMillis();
System.out.println("输出创建KieHelper用的毫秒是="+(end - start));
long startAddrule = System.currentTimeMillis();
//分别将规则myRuleFile2 myRuleFile1 加载到虚拟文件中
helper1.addContent(myRuleFile1, ResourceType.DRL);
helper2.addContent(myRuleFile2, ResourceType.DRL);//*******
long endAddrule = System.currentTimeMillis();
System.out.println("导入规则所用到的毫秒是="+(endAddrule - startAddrule));
long startNewKiesession = System.currentTimeMillis();
StatelessKieSession kieSession2 = helper1.build( ).newStatelessKieSession();
StatelessKieSession kieSession1 = helper1.build( ).newStatelessKieSession();
long endNewKiesession = System.currentTimeMillis();
System.out.println("创建有状态Kiesession所用到的毫秒是="+(endNewKiesession - startNewKiesession));
ExecutorService exec = Executors.newCachedThreadPool();
final Semaphore semp = new Semaphore(thread_num);
for (int index = 0; index < client_num; index++) {
Runnable run = new Runnable() {
public void run() {
try {
semp.acquire();
long startrule = System.currentTimeMillis();
Person person = new Person();
person.setName("张三");
person.setAge("" + (int) (Math.random() * 100));
School school = new School();
school.setName("北大");
school.setCount("40");
//设计两个List 同时将实体放在集合中
List cmds1 = new ArrayList();
List cmds2 = new ArrayList();
cmds1.add( CommandFactory.newInsert(person,"p1") );
cmds2.add( CommandFactory.newInsert(person,"p2") );
cmds1.add( CommandFactory.newInsert(school,"s1") );
cmds2.add( CommandFactory.newInsert(school,"s2") );
kieSession1.execute(CommandFactory.newBatchExecution(cmds1));
kieSession2.execute(CommandFactory.newBatchExecution(cmds2));
System.out.println(person.getName());
long endrule = System.currentTimeMillis();
System.out.println("规则执行所用到的毫秒是="+(endrule - startrule));
System.out.println("=============================牛逼的分割线=========================================");
semp.release();
} catch (Exception e) {
e.printStackTrace();
}
}
};
exec.execute(run);
}
exec.shutdown();
}
}