2016-11-29 14 views
0

У меня есть этот EJB Singleton (EJB 3.1):Блокировка от Singleton EJB в сессионный Bean

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

Мой боб является Tradicional EJB без гражданства Session Bean:

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

Мониторинг с VisualVM, Я понял, что некоторые потоки накапливаются. Приложение начиналось с Thread Live Peak = 92 и теперь составляет 102. И оно растет. В потоках VisualVM у меня есть несколько потоков со статусом «Парк» и «Подождите». В моей свалке Thread у меня много:

"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. Я не могу использовать LockType.WRITE, потому что я хочу выполнять call1SB() и call2SB() одновременно (у меня нет атрибутов в моих методах Singleton ..)

ответ

0

Механизмы блокировки 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 
} 

То же со вторым замком для вашего второго метода Singleton.