多线程将如何影响Easy Rules引擎?

时间:2016-09-07 02:13:21

标签: java multithreading rule-engine

我正在为我的网络应用程序寻找规则引擎,我找到了Easy Rules。但是,在FAQ部分中,它指出了线程安全的限制。

Web容器是否被视为多线程环境?对于HTTP请求,可能由应用程序服务器创建的工作线程处理。

线程安全如何到位?

How to deal with thread safety?

If you run Easy Rules in a multi-threaded environment, you should take into account the following considerations:

Easy Rules engine holds a set of rules, it is not thread safe.
By design, rules in Easy Rules encapsulate the business object model they operate on, so they are not thread safe neither.
Do not try to make everything synchronized or locked down! 

Easy Rules引擎是一个非常轻量级的对象,您可以为每个线程创建一个实例,这是避免线程安全问题的最简单方法

基于此示例,多线程将如何影响规则引擎?

public class AgeRule extends BasicRule {
    private static final int ADULT_AGE = 18;

    private Person person;

    public AgeRule(Person person) {
        super("AgeRule",
              "Check if person's age is > 18 and
               marks the person as adult", 1);
        this.person = person;
    }

    @Override
    public boolean evaluate() {
        return person.getAge() > ADULT_AGE;
    }

    @Override
    public void execute() {
        person.setAdult(true);
        System.out.printf("Person %s has been marked as adult",
                            person.getName());
    }

}

public class AlcoholRule extends BasicRule {

    private Person person;

    public AlcoholRule(Person person) {
        super("AlcoholRule", 
              "Children are not allowed to buy alcohol",
               2);
        this.person = person;
    }

    @Condition
    public boolean evaluate() {
        return !person.isAdult();
    }

    @Action
    public void execute(){
        System.out.printf("Shop: Sorry %s,
                you are not allowed to buy alcohol",
                 person.getName());
    }

}

public class Launcher {

    public void someMethod() {
        //create a person instance
        Person tom = new Person("Tom", 14);
        System.out.println("Tom:
                Hi! can I have some Vodka please?");

        //create a rules engine
        RulesEngine rulesEngine = aNewRulesEngine()
                .named("shop rules engine")
                .build();

        //register rules
        rulesEngine.registerRule(new AgeRule(tom));
        rulesEngine.registerRule(new AlcoholRule(tom));

        //fire rules
        rulesEngine.fireRules();
    }

}

1 个答案:

答案 0 :(得分:2)

是的,Web应用程序是多线程的。如您所料,服务器维护一个线程池。当serversocket在它正在侦听的端口上获取传入请求时,它会将请求委托给池中的线程。通常,请求在该线程上执行,直到响应完成。

如果您尝试创建单个规则引擎并让多个线程访问它,那么

  1. 规则引擎数据由于被多个线程操纵而被破坏(因为不意味着线程安全的数据结构可以执行多个步骤中的操作,这些步骤可能被其他线程干扰,因为它们是访问和更改相同的数据)或

  2. 您使用锁定来确保一次只有一个线程可以使用规则引擎,避免让您的共享对象损坏,但在此过程中会产生瓶颈。您的所有请求都需要等待规则引擎可用,并且一次只有一个线程可以取得进展。

  3. 为每个请求提供自己的规则引擎副本要好得多,因此它不会被破坏而且不需要锁定。线程的理想情况是每个线程都能够独立执行而无需争用共享资源。