2016-09-21 35 views
0

我有線程A維護數據結構(添加,刪除,更改ConcurrentHashMap中的值)。新線程是否具有完整內存 - 所有其他線程對共享對象的先前操作的可見性?

我有螺紋監聽套接字上偶爾創建線程Ç處理新的客戶端連接。

所有線程Ç旨意永遠只能從的ConcurrentHashMap讀取線程維護的(從不更新)。

是線程Ç保證看到由線程一個進行的所有更新,在的ConcurrentHashMap,螺紋Ç成立之前/被線程開始了嗎?

(編輯最後一句,使問題更加清晰:只關心更新到的ConcurrentHashMap)

+0

是的,服從Java內存模型*(q.v。)*之前發生的條款。基本上你需要確保每個訪問都是'synchronized'或'java.util.concurrent'等價的。謝謝 – EJP

回答

1

線程C是否保證在線程B被線程B創建/啓動之前看到由線程A執行的所有更新?

一般(例如,與普通HashMap),號

但(再次一般),如果線程下的線程A創建的,那麼答案是肯定的。

(有一個之前發生一個線程一個線程調用對象的start(),而新線程的run()方法的開始之間關係,但你已經推出了第三線索......並沒有描述任何會給你一個發生在鏈之間從A到B到C.)


但是,你是在談論一個ConcurrentHashMap這裏,和併發地圖有先天的內存一致性:

「內存一致性效果:當存在其他併發集合,之前放置在一個線程中的動作一個對象變爲ConcurrentMap作爲鍵或值發生 - 在訪問或從另一個線程中的ConcurrentMap中刪除該對象之後的動作之前。

(從ConcurrentMapjavadoc。)

因此,對於任何在多個線程共享一個ConcurrentHashMap只讀線程保證看到由另一個所做的更新...模的記錄的行爲迭代器。

+0

謝謝你這個全面的答案。我的問題很糟糕,我應該提到線程C只能從ConcurrentHashMap讀取,而不是詢問是否有任何更新可見(意味着可能更新非併發對象)。 – RonR

+0

我已經認爲是這樣。 –

1

是,如docs說:

反演反映最近完成的更新 結果持續發生的操作。 (更正式地說,對於一個給定的密鑰更新 操作蘊藏着之前發生的任何 (非空)檢索該鍵報告經更新的價值關係。)

1

是,如果ConcurrentHashMap對象共享全球或通過/共享/與thread C

1

你的短語

創建線程C-之前線程A執行/由線程B開始了嗎?

處理不明確的概念,因爲Java內存模型沒有提供基於時間順序的任何保證。您必須確保發生在之前,通過程序順序或通過同步順序進行排序,您似乎都沒有做。

因此,回答你的問題與「否」將是錯誤的,因爲這個問題有一個虛假的隱藏假設。

1

我對此很陌生,我想添加一些東西,Dariusz你不覺得更新值我們可以使用volatile修飾符。

糾正我,如果我錯了,volatile變量總是返回它的更新值。

相關問題