本文介紹了并發散列映射中值的原子更新-如何?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
任務是跟蹤一些正在運行的進程。將該信息保存在內存中很好,因此我使用并發散列映射來存儲該數據:
ConcurrentHashMap<String, ProcessMetaData> RUNNING_PROCESSES = new ConcurrentHashMap();
將新對象安全地放置到映射中是很好的,問題是這些進程的狀態會發生變化,所以我必須不時地更新ProcessMetaData
。我將ProcessMetaData
設置為不可變的,并使用ConcurrentHashMap
的compute()
方法更新值,但現在的問題是ProcessMetaData
變得更復雜,保持它不變很難管理。問題是–只要我只更新原子方法中的ProcessMetaData
(根據javadoc)compute()
,對象可能是可變的,總體上仍然是線程安全的?我的假設正確嗎?
推薦答案
只要您只訪問傳遞給compute
的函數內的值,在該函數中所做的修改就是安全的。
然而,這是一個毫無意義的理論觀點。將值存儲到集合或映射中的目的是最終檢索和使用它們。這就是問題的起點。
compute
方法返回結果值,就像get
返回當前存儲值一樣。一旦調用方開始使用該值,此使用可能與映射上的后續compute
操作并發。get
方法甚至可以在compute
操作正在進行時檢索值。允許非阻塞檢索操作是ConcurrentHashMap
的主要功能之一。因此,可能會發生各種爭用情況。
因此,使用可變對象并修改compute
中已經存儲的值只有在將map用作只寫內存時才是安全的,這是一種牽強的場景。當您使用不同的線程安全機制來確保所有更新在開始讀取映射之前都已完成時,它可能會起作用,但您的用例似乎有所不同。
這篇關于并發散列映射中值的原子更新-如何?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,