簡體   English   中英

Java並發數據結構

[英]Java concurrency data structure

我正在努力解決有趣的並發問題! 因為我有點困惑,不確定我是否理解正確。

在此輸入圖像描述

為了線程安全,我想使用ConcurrentMap

ConcurrentHashMap<String, BigDecimal> concurrentHashMap = new ConcurrentHashMap<String, BigDecimal>();

public BigDecimal getPrice(String id){
    return concurrentHashMap.get(id);
} 

public void updatePrice(String id, BigDecimal newPrice){
    concurrentHashMap.put(id, newPrice);
}
  1. 該解決方案是否可以保證線程安全的讀/寫? ConcurrentMap是這類問題的不錯選擇嗎?
  2. 如果我寫入鍵"a"它會鎖定整個Map還是寫入"b"鍵可用?
  3. 以下部分任務意味着什么? 如果在處理價格Pa1所花費的時間內,價格Pa2,Pa3和Pa4到達,則應用程序應處理的下一個價格是Pa4,並且應忽略所有先前的價格。 - 可能是我過於復雜的事情,但這是否意味着如果新的近期價格到貨,我不應該存儲和取消價格更新? 如果是,那么實現將如何?

謝謝你的幫助!

因此,您不會遇到任何死鎖情況,請嘗試以下方法:或者在嘗試使用資源之前,實現自己的標志以檢查資源是否正在使用。

public synchronized void updatePrice(String id, BigDecimal newPrice){
     concurrentHashMap.put(id, newPrice);
}

1. ConcurrentHashMap可以安全地用於多線程環境。

  1. 它不會鎖定整個地圖。 很可能你將能夠並行編寫b

  2. 這是最有趣的部分和問題本身。 假設您的updatePrice函數在存儲之前執行一些計算。 所以新的價格到達並到達,但你慢慢地逐個存儲......價格的隊列增加和增加....

您必須從輸入中讀取特定鍵的所有價格 - 丟棄第一個並且只取最后一個。 如果你說你的hashMap在中間。 在真正的處理之前,你是對的。 這就像解決問題一樣。

But! 如果價格經常出現,每次更新都會在內存堆(eden space)中生成新對象。 您的GC將從堆中清除所有這些價格。 所以,有趣的是要了解你是否可以在不同的處理器中訂閱不同的價格並且: 全部讀取它們。

該解決方案是否可以保證線程安全的讀/寫? ConcurrentMap是這類問題的不錯選擇嗎?

java.util.concurrent.ConcurrentHashMapHashMap線程安全實現,因此使用它將確保線程安全。 但請記住:

  • 即使所有操作都是線程安全的, 檢索操作也不需要鎖定 ,並且沒有任何支持以阻止所有訪問的方式鎖定整個表
  • 檢索操作(包括get)通常不會阻塞,因此可能與更新操作(包括put和remove)重疊。 檢索反映了最近完成的更新操作的結果

閱讀CHM的Java doc以獲取更多信息。

如果我寫入鍵“a”它會鎖定整個Map還是寫入“b”鍵可用?

是的,它將鎖定任何寫入操作的映射,如果寫入“a”正在進行,則寫入“b”將不可用,但映射對於讀取仍然是非阻塞的。

以下部分任務意味着什么? 如果在處理價格Pa1所花費的時間內,價格Pa2,Pa3和Pa4到達,則應用程序應處理的下一個價格是Pa4,並且應忽略所有先前的價格。 - 可能是我過於復雜的事情,但這是否意味着如果新的近期價格到貨,我不應該存儲和取消價格更新? 如果是,那么實現將如何?

這僅僅意味着“ 考慮最新價格 ”。

考慮到需求,您選擇使用Map是一個不錯的選擇,因為當您使用hashMap.put("pa", 123)時它將丟棄之前的值,因此每當您讀取hashmap時,您將始終讀取最新值。

如果確實不需要實現並發,您可能希望使用簡單的HashMap 並發應該是要求而不是選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM