final關鍵字是java中的一個很重要的關鍵字,但是經常被我們忽略。
final可以類,方法,變量。
使用final顯示的聲明變量是一個非常良好的編碼習慣,因爲java會對final修飾的變量進行內聯,提高代碼的性能。
最近正在看<Java Concurrenty in Practice> 這本書,裏面有一張是講解的利用final關鍵字構建一個線程安全的類,在此記錄
示例代碼如下:
public class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger lastNumber, BigInteger[] lastFactors) {
this.lastNumber = lastNumber;
this.lastFactors = lastFactors;
}
public BigInteger[] getFactors(BigInteger i) {
if(i == null || !lastNumber.equals(i)){
return null;
}else{
return Arrays.copyOf(lastFactors,lastFactors.length);
}
}
public class VoliatileCachedFactorizer implements Servlet{
private volatile OneValueCache cache = new OneValueCache(null,null);
@Override
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
//從請求中獲取因數
BigInteger i = extractFromRequest(req);
//查看緩存中是否有因數分解的結果
BigInteger[] factors = cache.getFactors(i);
if(factors == null){
//因數分解
factors = factor(i);
//創建因數分解緩存對象
cache = new OneValueCache(i,factors);
}
return encodeIntoResponse(resp,factors);
}
}
因爲OneValueCache對象中的兩個成員變量,lastNumber和lastFactors都是final修飾,所以OneValueCache對象是不可變的。這就保證了,如果線程A創建了OneValueCache對象,線程B對象無法修改線程A的OneValueCache對象中的兩個變量。線程B只能自己新建一個OneValueCache對象,同時OneValueCache對象使用了voliatile關鍵字修飾。所以線程B創建的OneValueCache對象的賦值操作可以立即對其他線程可見。