不同 KieHelper 不同Kiesession有状态

注不同KieHelper肯定是不同的Kiesession 但线程中试用则是唯一 只创建一次的不做修改的Kiesession

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.internal.conf.MultithreadEvaluationOption;
import org.kie.internal.utils.KieHelper;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class DrlKiesessionOneHelpers {
    private static int thread_num = 200;//线程数,设置同时并发线程数
    private static int client_num = 10;//访问次数
    /**
     * 测试 并发下 使用
     * 不同 KieHelper
     * 不同Kiesession有状态  注  不同KieHelper肯定是不同的Kiesession 但线程中试用则是唯一 只创建一次的不做修改的Kiesession
     */
    /**
     * 结论1:rule 名是能重复,这一点,符合kmodule.xml 规范要求 原因 虚拟文件在不同的虚拟目录中
     * 结论2:rule与rule之间的Fact会相互作用 虽然在代码中 分别将Person和School insert到 两个不同的Kiesession中
     *       但由于myRulefile1先执行,导致Fact对象发现变化 myRuleFile2规则无法满足条件
     * 结论3:虽然Kiesession是不同的,KieHelper是不同的,myRuleFile2与myRuleFile1都会被执行 但结果可能是存在迭代     *
     * 结论4:helper1.build(MultithreadEvaluationOption.YES).newKieSession();没有实际效果
     * 结论5:高并发下 有状态会迭代执行, 导致数据信息错误
     * 结论6:有状态创建的时间比无状态创建的时间要长
     * @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\" " +
                "   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();
        KieSession kieSession1 = helper1.build(MultithreadEvaluationOption.YES  ).newKieSession();
        KieSession kieSession2 = helper2.build(MultithreadEvaluationOption.YES ).newKieSession();
        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");
                        kieSession1.insert(person);
                        kieSession2.insert(person);
                        kieSession1.insert(school);
                        kieSession2.insert(school);
                        int s1 = kieSession1.fireAllRules();
                        int s2 = kieSession2.fireAllRules();
                        System.out.println("kieSession1执行规则"+s1);
                        System.out.println("kieSession2执行规则"+s2);
                        System.out.println(person.getName());
                        //kieSession1.dispose();//注释的原因  同一个Kiesession有状态 是线程以外创建的Kiesession 所以必须要注释
                        //kieSession2.dispose();//注释的原因  同一个Kiesession有状态 是线程以外创建的Kiesession 所以必须要注释
                        long endrule = System.currentTimeMillis();
                        System.out.println("规则执行所用到的毫秒是="+(endrule - startrule));
                        System.out.println("=============================牛逼的分割线=========================================");
                        semp.release();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            exec.execute(run);
        }
        exec.shutdown();
    }
}

 

你可能感兴趣的:(Drools规则引擎说明及应用)