在ReteMemory初始化期间阻塞的线程

时间:2016-01-29 08:29:07

标签: java multithreading drools blocking

在我的应用程序中,所有线程都在drools会话初始化期间阻塞

java.lang.Thread.State: BLOCKED
at org.drools.reteoo.common.ReteWorkingMemory.initInitialFact(ReteWorkingMemory.java:108)
    - waiting to lock <5385ba43> (a java.lang.Integer) owned by "Thead-23" t@42
    at org.drools.reteoo.common.ReteWorkingMemory.fireAllRules(ReteWorkingMemory.java:129)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1260)
    at org.drools.impl.adapters.StatefulKnowledgeSessionAdapter.fireAllRules(StatefulKnowledgeSessionAdapter.java:72)


java.lang.Thread.State: BLOCKED
at org.drools.reteoo.common.ReteWorkingMemory.initInitialFact(ReteWorkingMemory.java:108)
    - waiting to lock <5385ba43> (a java.lang.Integer) owned by "Thead-01" t@42
    at org.drools.reteoo.common.ReteWorkingMemory.fireAllRules(ReteWorkingMemory.java:129)
    at org.drools.core.impl.StatefulKnowledgeSessionImpl.fireAllRules(StatefulKnowledgeSessionImpl.java:1260)
    at org.drools.impl.adapters.StatefulKnowledgeSessionAdapter.fireAllRules(StatefulKnowledgeSessionAdapter.java:72)

复制问题的最简单方法是创建一个具有以下条件的drools文件: -

rule "slowWhenCondition" 
  when
      eval(mySlowCondition(fact))
  then

end

创建StatefulSession并从多个线程触发所有规则。使用JVisualVM或Stack Trace查看处于阻塞状态的线程。

在进一步调查后,我发现在ReteWorkingMemory初始化期间调用的以下代码导致了问题

private final Integer syncLock = 42;
public void initInitialFact() {
    if ( initialFactHandle == null ) {
        synchronized ( syncLock ) {
            if ( initialFactHandle == null ) {
                // double check, inside of sync point incase some other thread beat us to it.
                initInitialFact(kBase, null);
            }
        }
    }
}

用于锁定的整数常量会导致所有具有不相关规则的线程相互阻塞。最明显的解决方法是将syncLock从Integer常量更改为Object syncLock = new Object()。是否有任何理由不应该改变。

我正在研究Drools 6.3 Final并在CentOS上使用Java 8。应用程序中的每个线程都会创建自己的有状态会话。

1 个答案:

答案 0 :(得分:0)

此问题已通过建议的修复解决,现在是Drools 6.4的一部分。可在以下位置https://issues.jboss.org/browse/DROOLS-1046

找到更多信息