[英]Java ConcurrentHashSet - iterating over it in a multi-threaded environment
我已經看到了SynchronizedList的用例-他們聲明,在進行迭代時,即使SynchronizedList是線程安全的,我們也應該像這樣使用迭代器和同步塊-
synchronized(myList){
Iterator<Item> iterator = myList.iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next().getMessage());
}
}
例如,如果我使用ConcurrentHashSet(在Java 8中,可以使用並發HashMap的newKeySet()),那么在多線程環境中,是否仍然需要提取迭代器並使用同步塊? 我嘗試對其進行測試,但似乎沒有必要,但可能會遺漏一些東西。
謝謝!
對於我所知道的-從ConcurrentHashMap獲得的每個迭代器都設計為由單個線程使用,並且不應傳遞。
如果您嘗試同時使用多個線程來迭代Map,除非每個線程都使用它自己的迭代器,否則它將無法按預期工作。
帶有迭代器的ConcurrentHashMap的Concurrent是指您要在迭代時嘗試在映射中放置值或從中刪除值的情況-它將是線程安全的。 盡管不能保證另一個線程將看到更改,除非它從映射中獲取新的迭代器。
我希望這些信息有用!
ConcurrentHashMap.newKeySet()
返回:
/**
* Creates a new {@link Set} backed by a ConcurrentHashMap
* from the given type to {@code Boolean.TRUE}.
*
* @param <K> the element type of the returned set
* @return the new set
* @since 1.8
*/
public static <K> KeySetView<K,Boolean> newKeySet() {
return new KeySetView<K,Boolean>
(new ConcurrentHashMap<K,Boolean>(), Boolean.TRUE);
}
如您所見,它由ConcurrentHashMap支持。 您可以使用返回的實例,而無需任何同步。
.iterator()
方法返回一個新的KeyIterator
,由地圖的Node<K,V>[] table
因此,如果您在一個特定的線程中進行迭代,這意味着您將看到Node
數組的快照,並且每個節點處於正確狀態bc Node
內部具有易失性鏈接,但是您看到該鏈接的新元素添加到原始映射的可能性最小迭代器點不可變。 換句話說,您只是遍歷一個數組而沒有任何保證,如果該元素仍然存在於原始map atm中或在其中添加了一些新元素,但是您可以看到每個節點bc的最新狀態:
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
volatile V val;
volatile Node<K,V> next;
key
是最終的
val
易失
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.