DROOLS中的单线程执行?

DROOLS中的单线程执行?,drools,drools-flow,Drools,Drools Flow,我的应用程序处理多个请求,但知识会话中的规则仅由单个线程执行。 例如: 线程1和线程2以200毫秒的间隔进入知识会话 但是线程1执行自己的规则,甚至线程2的规则也由线程1执行。 想象一下,如果有1000个请求,这意味着每个请求的规则将仅由1个线程执行 在DROOLS中,有什么方法可以防止这种情况并确保规则由多个线程执行 下面是我尝试过的一个小样本测试: Java类: DRL文件 StatefulKnowledgeSessions不是线程安全的。如果您确实需要在多个线程上执行规则,请改用无状态Kn

我的应用程序处理多个请求,但知识会话中的规则仅由单个线程执行。 例如: 线程1和线程2以200毫秒的间隔进入知识会话 但是线程1执行自己的规则,甚至线程2的规则也由线程1执行。 想象一下,如果有1000个请求,这意味着每个请求的规则将仅由1个线程执行

在DROOLS中,有什么方法可以防止这种情况并确保规则由多个线程执行

下面是我尝试过的一个小样本测试:

Java类:

DRL文件


StatefulKnowledgeSession
s不是线程安全的。如果您确实需要在多个线程上执行规则,请改用
无状态KnowledgeSession
s重新格式化您的问题。

您可以在多线程环境中使用有状态知识会话。在应用程序启动之前,您必须将“KnowledgeBase”序列化为文件/db。之后,每个线程将不会创建自己的“KnowledgeBase”副本,而是将“KnowledgeBase”从“文件/db”反序列化


如果我们不序列化/反序列化“KnowledgeBase”,每个线程在需要时都会尝试加载规则并创建自己的“KnowledgeBase”,最后,如果线程数量增加,应用程序可能会抛出“java.lan.OutOfMemory permgen”“空间错误。因为每个线程都会尝试通过将类一次又一次地加载到内存中来创建自己的knowledgebase副本

嗯,但这不是询问者所呼叫的方法。返回所有活动会话,而不是新会话。
        import java.math.BigDecimal;

        import org.drools.KnowledgeBase;
        import org.drools.KnowledgeBaseFactory;
        import org.drools.builder.KnowledgeBuilder;
        import org.drools.builder.KnowledgeBuilderError;
        import org.drools.builder.KnowledgeBuilderErrors;
        import org.drools.builder.KnowledgeBuilderFactory;
        import org.drools.builder.ResourceType;
        import org.drools.io.ResourceFactory;
        import org.drools.runtime.StatefulKnowledgeSession;
import org.drools.runtime.rule.WorkingMemoryEntryPoint;
import org.springframework.context.support.ClassPathXmlApplicationContext;



        public class DJ_Test {

            public static void main(String[] args) {
                try {
                    System.out.println("In main");
                    // load up the knowledge base
                    KnowledgeBase kbase = readKnowledgeBase();
                    final StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
                    final WorkingMemoryEntryPoint entry =ksession.getWorkingMemoryEntryPoint("RequestStream");

                    final Object  obj_1= new Object();
                    Thread t1 = new Thread(){
                        public void run(){System.out.println(Thread.currentThread().getName() + " is running");
                        entry.insert(obj_1);
                        ksession.fireAllRules();
                        System.out.println(Thread.currentThread().getName() + " is terminated");
                        }
                        };

                   final Object  obj_2= new Object();
                   Thread t2 = new Thread(){
                    public void run(){
                    try{
                        Thread.sleep(8000); 
                    }catch(Exception e){

                    }
                    System.out.println(Thread.currentThread().getName() + " is running");
                    entry.insert(obj_2);
                    ksession.fireAllRules();
                    System.out.println(Thread.currentThread().getName() + " is terminated");
                    }
                    };
                  t1.start();
                  t2.start();





                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }

            private static KnowledgeBase readKnowledgeBase() throws Exception {
               /* KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
                kbuilder.add(ResourceFactory.newClassPathResource("rulesFlow.bpmn"), ResourceType.BPMN2);
                kbuilder.add(ResourceFactory.newClassPathResource("KansasSalesTax.drl"), ResourceType.DRL);
                kbuilder.add(ResourceFactory.newClassPathResource("MissouriSalesTax.drl"), ResourceType.DRL);
                kbuilder.add(ResourceFactory.newClassPathResource("SalesTax.drl"), ResourceType.DRL);
                KnowledgeBuilderErrors errors = kbuilder.getErrors();
                if (errors.size() > 0) {
                    for (KnowledgeBuilderError error: errors) {
                        System.err.println(error);
                    }
                    throw new IllegalArgumentException("Could not parse knowledge.");
                }
                KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
                kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
                return kbase;*/
                ClassPathXmlApplicationContext serviceContext = new ClassPathXmlApplicationContext( "droolsContext.xml" );
                return (KnowledgeBase) serviceContext.getBean("kbase1");
            }

            public static class DJ_Message {

                public static final int thread_1 = 1;
                public static final int thread_2 = 2;

                private String message;

                private int status;

                public String getMessage() {
                    return this.message;
                }

                public void setMessage(String message) {
                    this.message = message;
                }

                public int getStatus() {
                    return this.status;
                }

                public void setStatus(int status) {
                    this.status = status;
                }

            }

        }
package com.sample

import com.sample.DroolsTest.Message;

//global CepService cepService;
declare Object
    @role( event )
end


rule "rule_1"
salience 100
    when
        $o : Object() from entry-point RequestStream
    then
        System.out.println( "Rule 1 fired by " + Thread.currentThread().getName() );
        Thread.sleep(5000);

end


rule "rule_2"
salience 80
    when
        $o : Object() from entry-point RequestStream
    then
        System.out.println( "Rule 2 fired by " + Thread.currentThread().getName() );
        Thread.sleep(5000);

end

rule "rule_3"
salience 60
    when
        $o : Object() from entry-point RequestStream
    then
        System.out.println( "Rule 3 fired by " + Thread.currentThread().getName() );
        //cepService.executingThread1();
end

rule "4"
    when
        Message( status == Message.GOODBYE, myMessage : message )
    then
        System.out.println( myMessage );
        //cepService.executingThread2();
end