2016-05-13 80 views
5

我與同事討論了單例會話bean中的併發管理問題。根據我的理解,在閱讀Oracle documentation後,如果離開@ConcurrencyManagement註釋,那麼它默認爲容器管理的併發。在文檔它規定了以下有關容器管理的單會話bean:在Singleton會話Bean中管理併發訪問

的javax.ejb.Lock註釋和javax.ejb.LockType類型用於指定的單的業務方法或訪問級別@超時方法。

如果沒有@Lock註釋存在於單個類,默認鎖類型,@Lock(LockType.WRITE),被施加到所有的業務和超時的方法。

現在,如果你用@ConcurrencyManagement(ConcurrencyManagementType.BEAN)註釋豆,那麼你是負責確保Bean的狀態在使用​​關鍵字和其他標準的Java併發功能的所有客戶端同步。文章甚至說:

開發誰創建的bean管理的併發單身的允許使用Java編程語言的同步原語,如同步震盪,以防止併發訪問過程中出現錯誤。

我沒有看到在容器管理的併發的這部分的任何地方,導致我相信,如果你想自己的東西同步,你需要@ConcurrencyManagement(ConcurrencyManagementType.BEAN)其註釋類。

我的同事發表評論時說,當你看到豆子上的這個註釋時,「你們這些人做了一些奇怪的事情」,這開始了這個討論。

他的豆沒有任何@ConcurrencyManagement註釋,但他在整個類中使用​​關鍵字。我是否正確地說他正在使用的任何更細粒度的同步都是毫無意義的,因爲他所有的業務方法都有一個隱含的@Lock(LockType.WRITE)註釋?這意味着如果一個客戶端調用他的一個方法,那麼沒有其他客戶端可以調用該bean的任何方法,因此該方法內的顯式同步將毫無用處。

例如,對於synchronized (myLock)在其業務方法之一中使用的某些鎖myLock,由於這些方法實際上是同步的,因此不會爭用該鎖。

糾正我,如果我錯了,但似乎他的方法基本上是這樣的:

public synchronized void myMethod() { 
    // do stuff 
    synchronized (lock) { 
     // modify mutable state 
    } 
} 

public synchronized void myOtherMethod() { 
    // do other stuff 
    synchronized (lock) { 
     // modify mutable state 
    } 
} 

假設lock在此單會話bean剛創建的bean內保護可變狀態,它似乎它在使用容器管理的併發時不起任何作用。

在此先感謝您對此的任何洞察!

回答

0

一般而言,您對所有的期望都是正確的。有一個小例子,你的同事的代碼實際上可以使用同步原語。

如果存在ejb-jar.xml文件,它可以將併發管理設置爲由Bean管理。這將是這個樣子:

<enterprise-beans> 
    <session> 
     <ejb-name>MySingletonEJB</ejb-name> 
     <ejb-class>com.blah.MySingletonEJB</ejb-class> 
     <transaction-type>Bean</transaction-type> 
     ... 
    </session> 
... 
</enterprise-beans> 

由於EJB 3,這實在是一個糟糕的方式做的事情和註釋肯定是首選,因爲配置是正確與源。

+0

我不認爲這存在於我們的項目。他一直在說,「我已經這麼做了很多年,並且運行良好」,但他似乎並不明白我在說什麼。它會正常工作,但假設我正在閱讀的內容是正確的,他的「同步」塊將不再需要,並且不會提高吞吐量。 –

+0

我也很想測試他的代碼,看看他的同步是否真的在做什麼,但我有太多的事情要做......也許當我得到一些空閒時間:) –

0

你是對的,但它取決於他鎖定的內容,如果該對象綁定到該單身人士,那麼他確實是一個知道所有人實際上正在放慢執行程序的人,因爲雙重鎖定。