3 回答

TA貢獻1773條經驗 獲得超3個贊
cache對象在service()中只有一處寫操作(創建新的cache對象),其余都是讀操作,這里符合volatile的應用場景,確保cache對象對其他線程的可見性,不會出現并發讀的問題。
返回的結果是factors對象,factors是局部變量,并未使cache對象逸出,所以這里也是線程安全的。

TA貢獻1831條經驗 獲得超4個贊
一下個人理解:
(1).cache對象在service()中只有一處寫操作,但是多個線程都會執行這個寫操作。比如A線程帶入參數a1執行service方法之后,緩存里是number=a , lastFactors=[a];這時a2線程進入service方法帶入a,執行BigInteger[] factors = cache.getFactors(i); 取得了緩存數據[a]進行判斷時線程切換,來了個C線程帶入參數c執行完了方法。實際上此時的緩存是c和[c].理論上線程B讀的值已經是過期的了。。。只是因為“緩存”的業務意義使得這個過期值不會引起程序錯誤罷了。。。也就是說這個例子的線程安全體現在正好切合了這個業務。。。
(2).OneValueCache的不可變也是有限制的。BigInteger[]類型的數組接受外部參數后,用Arrays.copyOf能使得初始化后值不再變化。但是如果不是BigInteger類型而是其他類型,要保證該類型也是不可變對象才行。
總之我感覺,對于我這么菜的初學者來說,鎖還是最好用的。畢竟程序的優化是建立在沒有BUG的基礎上。萬一哪邊因為理解偏差導致隱含漏洞就跪了。

TA貢獻1780條經驗 獲得超1個贊
我覺得這個問題,對于常量類來說,多線程讀的操作不存在線程安全問題,但是寫的操作要看具體應用場景對于線程安全的定義。比如說《Java并發編程實戰》那段,我覺得作者對于線程安全就是只看當前的cache,最后達成一個緩存的目的,至于這個緩存能不能立馬用到不在乎,反正肯定有線程會用到的。
添加回答
舉報