2017-07-01 34 views
1

多線程應用程序需要訪問公用數據結構,該結構存儲已處理操作的列表。每個線程訪問的數據結構和:對集合的併發讀取/寫入訪問,比ConcurrentHashMap更快?

  • 如果運算它是關於做的已經存儲的數據集合中的ID,它將中止
  • 否則,將其寫入運算ID數據收集,並執行操作。

我比閱讀有更多的閱讀權限。

我使用的是一個ConcurrentHashMap這個公共數據結構由所有線程訪問。會發生什麼情況是,當操作數非常大(百萬)時,訪問ConcurrentHashMap的所有線程會同時減慢它們的速度。

這就是我正在嘗試解決的問題:使用可在多個線程中訪問的通用數據結構,而不會在縮放讀取訪問時受到損失。

我不需要讀取操作(數據結構中的操作ID)是否完全同步:可能發生操作將寫入數據結構,而讀取同時發生錯過它。這可能會使op被處理多次,但對於我的應用程序來說,這沒有問題。

進一步的細節:

  • 運算id不一定需要被保留
  • 運算IDS是一個對象,它是一個無序對整數。無序: 平等方法被覆蓋,以便對於給定的整數,對(L,R)==對(R,L)。完整的源代碼here

任何指針?

+2

用更大的塊給出你的操作,以便線程只需要檢查整個操作塊是否已經完成。這應該會減少對中央數據結構的爭用,因此您不需要比ConcurrentHashMap更快的事情。 –

+4

你確定'ConcurrentHashMap'是性能問題的來源嗎?閱讀它已經大部分是免費的,試試'ConcurrentHashMap'構造函數中的'concurrencyLevel'參數。 – 11thdimension

+2

這不太可能是併發性,這就是你的問題,更有可能你只是碰到了哈希映射的侷限性(主要碰撞加劇了它,取決於你的ID是什麼樣子)。見例如https://stackoverflow.com/questions/16693408/java-optimize-hashset-for-large-scale-duplicate-detection – CupawnTae

回答

-1

如果多線程訪問共享資源以使線程安全,則需要線程安全機制。

的ConcurrentHashMap:通過內部條紋鎖和16路的默認鎖。它意味着16線程同時執行更新操作而不會阻塞提供分佈evenly.If爲例所有的項目都屬於同一項目提高併發段,那麼它將不會有任何好處。所以首先分析並使用鎖定剝離,以便同時多線程執行更新操作而不會阻塞。如果未按預期執行,則可以使用非阻塞解決方案。

非阻塞:在您的用例中,大量線程嘗試訪問共享數據結構,這種爭用可能是一個解決方案,您可以探索執行更新操作CAS(比較和交換)的集合。 - 沒有自旋鎖 ─鎖住時沒有阻塞。 Link