迭代 ConcurrentHashMap 值线程安全吗? [英] Is iterating ConcurrentHashMap values thread safe?

查看:49
本文介绍了迭代 ConcurrentHashMap 值线程安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ConcurrentHashMap 如下:

检索操作(包括get)一般不会阻塞,所以可能与更新操作(包括put和remove)重叠.检索反映了最近完成的更新操作的结果.对于诸如 putAll 和 clear 之类的聚合操作,并发检索可能仅反映某些条目的插入或删除.类似地,迭代器和枚举返回反映哈希表在迭代器/枚举创建时或创建后的某个时刻的状态的元素.它们不会抛出 ConcurrentModificationException.但是,迭代器设计为一次只能由一个线程使用.

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset. For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration. They do not throw ConcurrentModificationException. However, iterators are designed to be used by only one thread at a time.

什么意思?如果我尝试同时使用两个线程迭代地图会发生什么?如果我在迭代时从地图中放入或删除一个值,会发生什么?

What does it mean? What happens if I try to iterate the map with two threads at the same time? What happens if I put or remove a value from the map while iterating it?

推荐答案

什么意思?

这意味着您从 ConcurrentHashMap 获得的每个迭代器都设计为由单个线程使用,不应传递.这包括 for-each 循环提供的语法糖.

That means that each iterator you obtain from a ConcurrentHashMap is designed to be used by a single thread and should not be passed around. This includes the syntactic sugar that the for-each loop provides.

如果我尝试同时使用两个线程迭代地图会发生什么?

What happens if I try to iterate the map with two threads at the same time?

如果每个线程都使用自己的迭代器,它将按预期工作.

It will work as expected if each of the threads uses it's own iterator.

如果我在迭代时在地图中放入或删除一个值会发生什么?

What happens if I put or remove a value from the map while iterating it?

如果您这样做,可以保证事情不会中断(这是ConcurrentHashMap 中并发"的含义的一部分).但是,不能保证一个线程会看到另一个线程执行的映射更改(无需从映射中获取新的迭代器).迭代器保证在地图创建时反映地图的状态.进一步的更改可能会反映在迭代器中,但并非必须如此.

It is guaranteed that things will not break if you do this (that's part of what the "concurrent" in ConcurrentHashMap means). However, there is no guarantee that one thread will see the changes to the map that the other thread performs (without obtaining a new iterator from the map). The iterator is guaranteed to reflect the state of the map at the time of it's creation. Futher changes may be reflected in the iterator, but they do not have to be.

总而言之,像这样的声明

In conclusion, a statement like

for (Object o : someConcurrentHashMap.entrySet()) {
    // ...
}

几乎每次看到它都会很好(或至少是安全的).

will be fine (or at least safe) almost every time you see it.

这篇关于迭代 ConcurrentHashMap 值线程安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆