代码之家  ›  专栏  ›  技术社区  ›  Akshay Gehi

ReteMemory初始化期间线程阻塞

  •  0
  • Akshay Gehi  · 技术社区  · 10 年前

    在我的应用程序中,所有线程都在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或堆栈跟踪观察处于阻塞状态的线程。

    在进一步调查之后,我发现在初始化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);
                }
            }
        }
    }
    

    用于锁定的Integer常量会导致具有不相关规则的所有线程相互阻塞。最明显的修复是将syncLock从Integer常量更改为Object syncLock=new Object()。有什么理由不应该改变它吗。

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

    1 回复  |  直到 10 年前
        1
  •  0
  •   Akshay Gehi    10 年前

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