[英]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.