簡體   English   中英

易失性與最終性。 這邊的final有什么用

[英]volatile vs final. What is the use of final over here

下面是實踐中並發的代碼片段。

class OneValueCache {          
private final BigInteger lastNumber;  
private final BigInteger[] lastFactors;  
public OneValueCache(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);  
}  
}


//Volatile is not enough to make VolatileCachedFactorizer thread safe? Why we need final   specifier in OneValueCache. 
public class VolatileCachedFactorizer implements Servlet {  
  private volatile OneValueCache cache = new OneValueCache(null, null); 
  //Servlet service method. 
  public void service(ServletRequest req, ServletResponse resp) {  
     BigInteger i = extractFromRequest(req);  
     BigInteger[] factors = cache.getFactors(i);
     //Check factors are null or not.  
     if (factors == null) {  
       factors = factor(i);  
       cache = new OneValueCache(i, factors);  
     }  
     encodeIntoResponse(resp, factors);  
  }  
} 

在OneValueCache中將字段聲明為final的用途是什么。 “易失性OneValueCache緩存”確保該對象對所有其他線程可見,並且我假定對易失性寫入之前的所有其他線程可見該對象。

最終字段使OneValueCache不可變,從而使其成為線程安全的。 它們還具有JLS定義的特殊語義,特別是,任何線程都將能夠看到將最終字段初始化為其唯一正確值的正確構造的對象。

如果不是這種情況,並且字段恰好不是final,則其他線程可能也看不到更改,即使在構造函數中也是如此,因為如果沒有final字段,就無法保證構造安全。

JCIP解釋說,OneValueCache只是一個不變的引用類,用於保存數據的兩位。 這比更新方法中的兩個字段更安全,因為它不是原子的。 然后,由於需要更改OneValueCache,因此它在servlet中變得易失,但這是一個原子分配,因此不需要同步。

他們是兩個不同的東西。 通常,

volatile >創建一個內存屏障,以強制刷新高速緩存中的數據並強制從主內存中讀取數據。 因此,所有線程始終可以獲取該特定字段的更新數據。

final ->

  1. 對於基元->指定該值不能更改

  2. 對於非基元->引用不能更改(即,引用不能指向另一個對象)。 為了使對象/字段不可變 ,您需要確保最終字段可傳遞地訪問該對象/字段,並且對它的引用不會進行轉義。

PS: 最終不變性是兩個不同的概念。 因此,如果您聽說過不可變性,請理解它與final 有所不同

看起來OneValueCache類的意圖是不可變的,因此將值聲明為final只是為了保證程序員在以后的某個階段不嘗試擴展該類並覆蓋這些值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM