concurrentMap.keySet().toArray() 线程安全吗?

Is concurrentMap.keySet().toArray() thread safe?

我有一个ConcurrentHashMap<String, Object> concurrentMap;

我需要 return String[] 和地图的键。

就是下面的代码:

  public String[] listKeys() {
    return (String[]) concurrentMap.keySet().toArray();
  }

线程安全?

虽然 ConcurrentHashMap 是线程安全的 class,但 Iterator在键上使用 NOT CERTAIN 与任何后续 HashMap 更改同步,一旦创建...

来自spec

    public Set<K> keySet()

    Returns a Set view of the keys contained in this map......
    ...........................

    The view's iterator is a "weakly consistent" iterator that will 
    never throw ConcurrentModificationException, and guarantees to 
    traverse elements as they existed upon construction of the iterator, 
    and may (but is not guaranteed to) reflect any modifications 
    subsequent to construction.

是也不是。只有当您扩展到范围时,才会模糊定义威胁安全。

通常,并发集合以允许多个线程并发访问的方式实现它们的所有方法,或者如果不能,则提供透明地序列化此类访问(例如同步)的机制。因此,从某种意义上说,它们是安全的,因为它们确保它们保留了有效的内部结构并且方法调用给出了有效的结果。

如果你看细节,就会开始模糊,例如toArray() 将 return 为您提供集合内容的某种 快照。无法保证到方法 returns 时内容还未更改。因此,虽然调用是线程安全的,但结果将 not 满足通常的不变量(例如,数组内容可能 not 与集合相同) .

如果您需要在对并发集合的多次调用范围内保持一致性,则需要在调用方法的代码中提供机制以确保所需的一致性。