2 回答

TA貢獻(xiàn)2003條經(jīng)驗(yàn) 獲得超2個(gè)贊
我不確定您在第二個(gè)示例中要做什么,您有 (1) 一個(gè)不必要的構(gòu)造函數(shù)和字段,以及 (2) 一個(gè)不必要的安全映射(沒有更多信息,我擔(dān)心這是無用的)。您的第一個(gè)解決方案是兩者中最“正確”的,除非您想修改secId
(在這種情況下,您需要在Security
類中進(jìn)行額外的同步)。
我認(rèn)為最理想的解決方案是ConcurrentHashMap
在這種情況下使用并取消鎖定。

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超3個(gè)贊
您遇到了簡單并發(fā)結(jié)構(gòu)的問題,即更新結(jié)構(gòu)需要您鎖定整個(gè)結(jié)構(gòu),無論使用的是什么密鑰。這顯然會損害并發(fā)性。您的緩存必須可供所有線程訪問,因此鎖定它會阻止所有其他嘗試訪問該結(jié)構(gòu)的線程。
這樣做的原因是添加或刪除條目會導(dǎo)致映射中的內(nèi)部結(jié)構(gòu)被修改,從而影響其他鍵。所以你必須鎖定整個(gè)結(jié)構(gòu)。
您的第一個(gè)解決方案將起作用,但與將地圖包裝在 a 中SynchronizedMap
(可能更糟)相同。
您的第二個(gè)解決方案有很多錯(cuò)誤,但通常它不會起作用,因?yàn)樗粫i定地圖。
有兩種前進(jìn)方式:
如果您事先知道所有證券是什么,您可以預(yù)先構(gòu)建包含所有已知密鑰的緩存。我相信您然后可以獲取和放置并且您不需要同步,因?yàn)槟粫采w現(xiàn)有的地圖條目。如果您真的想確定,您可以在地圖中創(chuàng)建一個(gè) Price 類作為價(jià)值項(xiàng)目,其中包含您可以修改的價(jià)格,然后使用 Price 對象預(yù)加載緩存,然后修改 Price 對象中的價(jià)格字段。您將永遠(yuǎn)不必在初始加載后執(zhí)行 get 和 put 操作。
如果您事先不知道所有鍵或者不想預(yù)加載緩存,請使用
ConcurrentHashMap
.ConcurrentHashMap
確實(shí)同步,但它在內(nèi)部創(chuàng)建了多個(gè)段,并有巧妙的策略來分割一組鍵,這樣它就不必鎖定整個(gè)地圖,只需要鎖定一個(gè)段。這意味著很有可能避免緩存中的爭用。手動(dòng)條目指出讀取通常不會阻塞,并且可以向構(gòu)造函數(shù)指定并發(fā)值以控制預(yù)期的并發(fā)線程數(shù)。
添加回答
舉報(bào)