簡體   English   中英

Java並發:鎖定效率

[英]Java Concurrency: lock effiency

我的程序有100個線程。

每個線程都這樣做:

1)如果arrayList為空,則向其添加具有某些屬性的元素

2)如果arrayList不為空,則遍歷在arrayList中找到的元素,如果找到合適的元素(匹配某些屬性),則獲取它並刪除arrayList

這里的問題是,當一個線程迭代通過arrayList時,其他99個線程正在等待arrayList上的鎖。

如果我希望所有100個線程都能在無鎖狀態下工作,您會向我建議什么? 所以他們都有工作要做?

謝謝

你看過共享和獨占鎖嗎? 您可以在列表中使用共享鎖,然后在列表元素上使用“已刪除”屬性。 用於檢查列表元素的謂詞需要確保除了您擁有的任何其他查詢之外,該元素未標記為“已刪除” - 由於潛在的讀寫沖突,您需要鎖定每個元素,因為遍歷。 然后定期獲取列表上的獨占鎖以執行實際刪除。

讀鎖允許列表上的大量並發。 列表中每個元素的獨占鎖定不是很好,但是您需要強制內存模型將每個線程的“已刪除”標志更新,因此無法解決這個問題。

首先,如果您沒有在具有64個核心或更多核心的計算機上運行,​​那么您的100個線程可能本身就是一個性能損失。

那么對於你描述一個ArrayList肯定不是一個好的選擇,因為移除元素分期常量時間,但在線性時間為O(n) 運行。 所以這是第二次表現。 您可能希望使用LinkedList而不是ArrayList(如果您堅持使用List)。

當然,我當然非常懷疑每次需要找到一個元素時都需要迭代完整列表:不會有其他數據結構更合適嗎? 也許您放入列表中的元素具有“相等”的概念,因此可以使用具有O(1)查找時間的Map?

這只是一個開始:正如我向您展示的那樣,您所描述的內容至少存在兩個嚴重的性能問題....如果您需要更多幫助,也許您應該澄清您的問題。

如果您的“合適元素(匹配某些屬性)”的概念可以使用Comparator器進行編碼,那么PriorityBlockingQueue將允許每個線程輪詢隊列,獲取下一個元素而不必搜索列表或者如果隊列是隊列則將新元素排入隊列空。

附錄: Thilo提出了一個要點:隨着您的方法的發展,您可能需要根據經驗確定最佳線程數。

關鍵是只在實際需要時才使用arraylist上的對象鎖。

一個好主意是將arraylist子類化,並在單個讀取+寫入+刪除過程中提供同步。

這將確保鎖定的精細粒度,同時允許線程在陣列列表中運行,同時保護arraylist的語義。

讓一個線程擁有該數組並負責添加它並迭代它以找到要做的工作。 找到工作單元后,將工作放在BlockingQueue上。 讓所有工作線程使用take()從隊列中刪除工作。

這允許每次通過陣列發現多個工作單元,並且它們可以相當有效地切換到等待工作線程。

暫無
暫無

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

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