2015-12-14 34 views
3

按Java併發存儲複雜對象可以拋出斷言錯誤:在下面的代碼實踐的ConcurrentHashMap

如果不是出版線程以外的線程都調用 assertSanity,它可能拋出的AssertionError

public class Holder { 
private int n; 
public Holder(int n) { this.n = n; } 
public void assertSanity() { 
if (n != n) 
throw new AssertionError("This statement is false."); 
} 
} 

// Unsafe publication 
public Holder holder; 
public void initialize() { 
holder = new Holder(42); 
} 

問題是:如果我保存,這是指與其他對象在ConcurrentHashMap中的對象,有一種可能性,即在該對象圖某些更新將不同步,在多線程環境中,由於同樣的理由,提到的上面的例子?

在對象圖

雖然根節點總是會在地圖更新所有線程,但對於被稱爲根節點領域的其他對象,如果這些都不是最終的或揮發性?

回答

1

回答我的問題,我應該問的問題之前閱讀完整篇。這是後面章節的部分說:

Mutable objects: If an object may be modified after construction, safe publication ensures only the visibility of the as-published state. Synchronization must be used not only to publish a mutable object, but also every time the object is accessed to ensure visibility of subsequent modifications. To share mutable objects safely, they must be safely published and be either thread-safe or guarded by a lock.

因此,使用中藥或任何線程安全的集合是在多線程環境中是不安全的,除非你在同步CHM更改您的可變對象或這些對象是不可變的。

1

ConcurrentHashMap保證所有帶引用(鏈接到對象)的操作(保存在ConcurrentHashMap中)都是線程安全的,但是當然,ConcurrentHashMap不能保證每個對象都有線程安全的引用(鏈接)存儲在一個ConcurrentHashMap中。

+0

所以你的意思是,在對象圖的變化將是不同步的,如果同一CHM是在不同的線程訪問? – Mohit

+0

如果我們談論的對象圖,所有節點的鏈接僅保存CHM,是的,它是同步。 –

+0

我還沒有直接回答,可能是我的問題不清楚。在CHM你只要把單個節點(對象),我知道是保證同步,但對於幾個對象(在這些節點域)到這些節點是指哪些? – Mohit