2 回答

TA貢獻(xiàn)1802條經(jīng)驗 獲得超5個贊
第一個問題。
locks
在這種情況下,線程安全取決于對包含and buckets
(我們稱之為)的對象的引用是否Container
被正確共享。
試想一下:一個線程正忙于實例化一個新Container
對象(分配內(nèi)存、實例化數(shù)組等),而另一個線程開始使用這個半實例化的對象,其中locks
和buckets
仍然為 null(它們還沒有被第一個線程實例化)。在這種情況下,這段代碼:
synchronized (locks[bucketNum]) {
變得破碎并拋出NullPointerException
。關(guān)鍵字final
可以防止這種情況發(fā)生,并保證當(dāng)對的引用不為空時Container
,其最終字段已被初始化:
當(dāng)對象的構(gòu)造函數(shù)完成時,該對象被認(rèn)為已完全初始化。僅在對象完全初始化后才能看到對該對象的引用的線程保證能看到該對象的最終字段的正確初始化值。( JLS 17.5 )
第二個問題。
假設(shè)locks
和buckets
字段是最終的,并且您不關(guān)心整個數(shù)組的一致性,并且“每個存儲桶 [i] 只在 lock[i] 下修改”,則此代碼很好。

TA貢獻(xiàn)2011條經(jīng)驗 獲得超2個贊
在你問的第一個問題中
由于“桶”是最終的,因此即使沒有同步,也不會有任何可見性問題。我的猜測是,通過同步,如果沒有最終結(jié)果,也不會有任何可見性問題,這是正確的嗎?
我不確定你所說的“可見性問題”是什么意思,但可以肯定的是,synchronized
如果多個線程訪問buckets[i]
其中一個線程并修改它(例如寫入它),那么如果沒有這段代碼,這段代碼將是不正確的。無法保證一個線程所寫入的內(nèi)容對另一線程可見。這還涉及存儲桶的內(nèi)部結(jié)構(gòu),可能會通過調(diào)用來修改add
。
請記住,final
onbuckets
僅涉及對數(shù)組本身的單個引用,而不涉及其單元格。
添加回答
舉報