使用final關鍵字創建一個線程安全的類

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對象的賦值操作可以立即對其他線程可見。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章