不變性

不可變對象一定是線程安全的

那么什么是不可變對象呢?

當(dāng)滿足一下條件時,對象才是不可變的。

  • 對象創(chuàng)建以后其狀態(tài)就不能修改
  • 對象的所有域都是final類型
  • 對象是正確創(chuàng)建的(在對象的創(chuàng)建期間,this引用沒有逸出)

我們回到之前因數(shù)分解的例子,通過構(gòu)造一個不可變類來實現(xiàn)同步:

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);
        }
    }
}

public class VolatileCachedFactorizer implements Servlet{
    private volatile OneValueCache cache = 
        new OneValueCache(null,null);

    public void service(ServletRequest req, ServletResponse resp){
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = cache.getFactors(i);
        if (factors == null) {
            factors = factor(i);
            cache = new OneValueCache(i, value);
        }
        encodeIntoResponse(resp, factors); 
    }
}

我們可以看到OneValueCache為一個不可變類,并且我們在創(chuàng)建時,使用volatile關(guān)鍵字聲明,這樣保證了線程安全性和可見性。

但要注意的一點是:
如果final類型的域所指向的是可變對象,那么在訪問這些域所指向的對象的狀態(tài)時仍然需要同步

public final class ThreeStooges {
  private final Set<String> stooges = new HashSet<String>();

  public ThreeStooges() {
    stooges.add("Moe");
    stooges.add("Larry");
    stooges.add("Curly");
  }

  public boolean isStooge(String name) {
    return stooges.contains(name);
  }

  public synchronized Set<String> getStooges(){
    return stooges;
  }
}

如上,stooges變量為可變對象,因此,如果我們需要對其訪問時,需要加上synchronized關(guān)鍵字來保證同步。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,687評論 0 11
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,754評論 18 399
  • 可見性 當(dāng)一個線程修改了對象狀態(tài)后,其他線程能夠看到發(fā)生的狀態(tài)變化 如何保證? 加鎖,當(dāng)線程B執(zhí)行由鎖保護(hù)的同步代...
    Cafebaby閱讀 570評論 0 2
  • 幾年前開始看塔莎奶奶的書,并深深的被她的生活方式所吸引,今日再讀她的傳家寶,又添佩服之情…… 且羅列下...
    aqiao閱讀 643評論 1 1
  • 對騰訊火熱推出的微信小程序進(jìn)行超快的入門,快速掌握微信小程序的入門及基礎(chǔ)知識學(xué)習(xí)技巧,并帶您搞定一個網(wǎng)絡(luò)博客小程序!
    小波yagamis閱讀 416評論 0 0