2016-11-29 9 views
0

私はこのEJBシングルトン(EJB 3.1)を有し、VisualVMのを監視ロック伝播

@Stateless 
public class StatelessSBExample { 
    public void domSomething() { 
    ... 
    } 
} 

@Singleton 
@Startup 
@Lock(LockType.READ) 
public class SingletonExample { 

@EJB 
private StatelessSBExample stlsb; 
... 
    @Schedule(..........., persistent = false) 
    @AccessTimeout(0) 
    @Lock(LockType.READ) 
    public void call1SB() { 
     stlsb.doSomething(); 
    } 

    @Schedule(..........., persistent = false) 
    @AccessTimeout(0) 
    @Lock(LockType.READ) 
    public void call2SB() { 
     stlsb.doSomething(); 
    } 
} 

マイBeanはtradicional EJBステートレスセッションBeanであります私はいくつかのスレッドが蓄積していることに気づいた。アプリケーションはThread Live Peak = 92で始まり、現在は102です。そして、それはますます増えています。 VisualVMスレッドでは、ステータスが "Park"と "Wait"のスレッドがいくつかあります。私のせいでは

"Thread-42" - Thread [email protected] 
    java.lang.Thread.State: WAITING 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <71bfce05> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088) 
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

    Locked ownable synchronizers: 
    - None 

"__ejb-thread-pool13" - Thread [email protected] 
    java.lang.Thread.State: WAITING 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <5cfe398e> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) 
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) 
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) 
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 

    Locked ownable synchronizers: 
    - None 

です:私のスレッドダンプで は私が多くを持っていますか? call1SB()を実行したいだけで、実行中の場合はこのメソッドを再度実行しません(call2SBと同じ)。

P.S. call1SB()とcall2SB()を同時に実行したいのでLockType.WRITEを使用することはできません(私のシングルトンでは属性はありません..)。

答えて

0

デフォルトのEJBロックメカニズムは、非常に柔軟ではありません。 2番目のシングルトンメソッドの第2のロックと同じ

private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); 

public void call1SB() { 
    if(lock.writeLock().tryLock()) { 
    // Acquires the write lock only if it 
    // is not held by another thread at the time of invocation. 
     stlsb.doSomething(); 
    } // else { return; } // do nothing if already locked 
} 

:そのような場合には、ここで私はこのような独自のロック機構を使用することをお勧めします。