锁定从Singleton EJB到无状态会话bean的传播



我有这个ejb singleton(ejb 3.1):

@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是一个传统的EJB无状态会话bean:

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

用VisualVM监视,我意识到有些线程正在积累。应用程序从线程Live Peak = 92开始,现在为102。它正在增加。在VisualVM线程中,我有几个线程具有" Park"one_answers" Wait"的状态。在我的线程转储中,我有很多:

"Thread-42" - Thread t@190
   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 t@130
   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。我不能使用locktype.write,因为我想同时执行call1sb()和call2sb()(我在singleton中没有属性..只有方法)

默认的EJB锁定机制在常见用例中正常工作,但它们不是很灵活。在这种情况下,我建议使用您自己的锁定机制:

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
}

与第二个单身方法的第二个锁相同。

最新更新