ReteMemory 初始化期间阻塞的线程
Threads blocking during ReteMemory initialization
在我的应用程序中,所有线程在 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 constant 更改为 Object syncLock = new Object()。有什么理由不应该改变它吗?
我正在开发 Drools 6.3 Final 并在 CentOS 上使用 Java 8。应用程序中的每个线程都创建自己的有状态会话。
该问题已通过建议的修复程序解决,现在是 Drools 6.4 的一部分。可以在以下位置找到更多信息 https://issues.jboss.org/browse/DROOLS-1046
在我的应用程序中,所有线程在 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 constant 更改为 Object syncLock = new Object()。有什么理由不应该改变它吗?
我正在开发 Drools 6.3 Final 并在 CentOS 上使用 Java 8。应用程序中的每个线程都创建自己的有状态会话。
该问题已通过建议的修复程序解决,现在是 Drools 6.4 的一部分。可以在以下位置找到更多信息 https://issues.jboss.org/browse/DROOLS-1046