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






