2016-11-29 73 views
0

我有這個EJB辛格爾頓(EJB 3.1):鎖傳播到Stateless Session 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(); 
    } 
} 

我bean是一個tradicional EJB無狀態會話Bean:

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

監測與VisualVM的,我意識到一些線程正在積累。該應用程序以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(),如果它正在運行,不再執行此方法(與調用2SB相同)

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 
} 

同樣用第二個鎖定你的第二個辛格爾頓方法。

相關問題