Search code examples
javamultithreadingdroolsblocking

Threads blocking during ReteMemory initialization


In my application, all threads are blocking during initialization of drools session

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)

The easiest way to replicate the issue is by creating a drools file with the following condition:-

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

end

Create a StatefulSession and fire all the rules from multiple threads. Observe the threads in Blocking state using JVisualVM or Stack Trace.

Upon investigating further I figured that the following code which is invoked during the initialization of ReteWorkingMemory is causing the problem

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);
            }
        }
    }
}

An Integer constant used for locking causes all threads having unrelated rules to block on each other. The most obvious fix is changing the syncLock from Integer constant to Object syncLock = new Object(). Is there any reason why it should not be changed.

I am working on Drools 6.3 Final and using Java 8 on CentOS. Each thread in the application creates its own Stateful Session.


Solution

  • The issue has been resolved by the suggested fix and is now a part of Drools 6.4. More information can be found at the following location https://issues.jboss.org/browse/DROOLS-1046