安全发布java.util.concurrent集合

ass*_*ias 6 java concurrency thread-safety

这段代码中的volatile是多余的吗?

public class Test {
    private volatile Map<String, String> map = null;

    public void resetMap() { map = new ConcurrentHashMap<>(); }

    public Map<String, String> getMap() { return map; }
}
Run Code Online (Sandbox Code Playgroud)

换句话说,确实map = new ConcurrentHashMap<>();提供任何可见性保证吗?

据我所知,唯一的保证ConcurrentMap是:

在将对象作为键或值放入ConcurrentMap之前的线程中的操作发生在从另一个线程中的ConcurrentMap访问或删除该对象之后的操作之前.

java.util.concurrent中的其他线程安全集合(CopyOnWriteArrayList等)怎么样?

Pet*_*rey 8

volatile因为您要更改对地图的引用,所以不是多余的.即ConcurrentMap仅提供有关集合内容的保证,而不是对它的引用.

另一种选择

public class Test {
    private final Map<String, String> map = new ConcurrentHashMap<>();

    public void resetMap() { map.clear(); }

    public Map<String, String> getMap() { return map; }
}
Run Code Online (Sandbox Code Playgroud)

java.util.concurrent中的其他线程安全集合(CopyOnWriteArrayList等)怎么样?

只有集合的行为是线程安全的.对集合的引用不是线程安全的,通过将集合中的元素添加到集合中,元素中的元素不会成为线程安全的.


Tom*_*icz 6

volatile在这里是必要的.它适用于参考,而不适用于它所引用的内容.换句话说,对象是线程安全的并不重要,其他线程将不会看到map字段的新值(例如,可能会看到先前引用的并发映射或null).

而且,即使你的对象是不可变的(例如String),你仍然需要volatile,更不用说其他线程安全的集合了CopyOnWriteArrayList.