2012-03-27 69 views
3

這是我的代碼..如何以及爲什麼此代碼是線程安全的..?

@immutable // This is not a standard annotation .Only for Showing that behavior of Class 
class OneValueCached{ 
    private final BigInteger lastNumber; 
    private final BigInteger[] lastFactors; 
    public OneValueCached(BigInteger i,BigInteger[] factors){ 
     lastNumber=i; 
     lastFactors=Arrays.copyOf(factors, factors.length); 
    } 

    public BigInteger[] getFactors(BigInteger i){ 
     if(lastNumber==null || !lastNumber.equals(i)) 
      return null; 
     else 
      return Arrays.copyOf(lastFactors, lastFactors.length); 
    } 
} 

@threadSafe // This is not a standard annotation .Only for Showing that behavior of Class 
public class VolatileCachedFactorizer implements Servlet{ 
    private volatile OneValueCached cache=new OneValueCached(null, null); 

    public void service(ServletRequest req, ServletResponce resp){ 
     BigInteger i= extractFromRequest(req); 
     BigInteger[] factors=cache.getFactors(i); 
     if(factors==null){ // ---> line 1 
      factors=factor(i); // --> line 2 
      cache=new OneValueCached(i, factors); 
     } 

     encodeIntoResponse(resp,factors); 
    } 
} 

爲什麼類VolatileCachedFactorizer是線程根據但我的觀點是...
1 @ 1號線如果2線程在同一時間到來在這一點上第一個thread檢查條件,發現因子= null和第二個thread也檢查同一條件後第1 thread暫停在線第2發現係數= NULL
,都將是創造新的OneValueCached對象的代碼再怎麼是線程安全的。根據預訂是線程安全的..

感謝的

+0

「@ threadSafe」是什麼註釋?它可能是打字錯誤,也可能不是標準註釋,因爲標準命名約定是'@ ThreadSafe'。 (相同的@ @不可變) – Thomas 2012-03-27 06:57:22

+0

只是爲了通知,我知道這不是一個標準註釋... – 2012-03-27 06:58:37

+2

'return lastFactors = Arrays.copyOf(lastFactors,lastFactors.length);'看起來很奇怪。它大概是內部數組的防禦副本,但是也會將內部狀態重新分配給它發出的同一個副本。這不再是防禦或不可改變的。其實,這是一個編譯錯誤,因爲'lastFactors'是最終的,不是? – Thilo 2012-03-27 07:11:01

回答

3

這是線程安全的,因爲有從未在lastNumberlastFactors之間產生不一致,這可能會導致錯誤的因子分解。它不保證最小數量的保理會發生:OneValueCached可以創建多次,但這仍然是線程安全的。

+0

謝謝,我明白了。 :) – 2012-03-27 07:24:19

1

「線程安全性」的確切概念尚未在此處定義。你希望這個代碼是線程安全的嗎?

  1. 如果您期望涉及的所有對象的狀態(就我所知,在此代碼中)是一致的,那麼它是線程安全的(如@artbristol解釋)。
  2. 如果您期望同時調用service時創建一個Cache對象,則它不是線程安全的。

再一次,沒有爲這種情況定義線程安全行爲,我們無法真正說清楚。

0

此代碼是線程安全的。但我不認爲Array.copyOf()在構造函數中是必要的。

0

雖然這是一年多以前提出的問題,但我仍然想給出我的解釋。 實際上,這段代碼是從第40頁的「Java Concurrency in Practice」中採用的。作者聲稱VolatileCachedFactorizer是一個線程安全的servlet,因爲servlet程序本身是由用戶同時調用的。所以作者意味着如果可變 - -OneValueCached緩存可以一致地被線程讀寫,這意味着不會導致諸如lastNumber和lastFactors不匹配的情況,那麼它將是線程安全的。我很困惑的是,本書聲稱只有在Arrays.copyOf()函數被使用,它將是線程安全的。但爲什麼?爲什麼需要Arrays.copyOf()?

0

Qisen,回答你的問題,需要Arrays.copyOf(),否則OneValueCache將不會是不可變的。如果在構建OneValueCache時沒有複製這些因素,那麼您應該讓數組的引用(直到該點位於運行線程本地)轉義。

相關問題