一次写入数组/集合/映射内容的安全发布

问题描述 投票:0回答:1

主要问题:用Java执行安全发布数组,集合或映射的内容的最佳方法是什么?

这是我尝试过的,还有一些附带问题:


侧面问题#1

在线程1上,我正在写入HashMap

HashMap

我目前的理解是:

  • [Map<K, V> map = new HashMap<>(); map.put(key, value); 并不构成地图中存储的参考的安全发布。

  • 通过检查Collections.unmodifiableMap()的实现,结果:

    • [Collections.unmodifiableMap()是线程安全的。
    • [Map.of()是线程安全的。
    • [Map.of()及更高版本不是线程安全的。

我错了吗?


侧面问题2

现在,我想安全地公开在读取之前写入的Map.of()的内容。我目前的理解是使用Map.of(key, value)会导致性能下降,因此我宁愿避免在这种情况下使用它。

我想出了这种选择:

Map.of(key, value)

正确吗?有更好的方法吗?


侧面问题3

在线程1上,我正在写一个易失性数组:

Map.of(key1, value1, key2, value2)

我目前的理解是,从另一个线程读取Map.of(key1, value1, key2, value2)是不安全的。为了安全起见,必须使用HashMap

这里是HashMap的摘录:

ConcurrentHashMap

如果ConcurrentHashMap无法获得与class MapSafePublication<K, V> { private final Map<K, V> map = new HashMap<>(); private final ThreadLocal<Map<K, V>> safeMap = ThreadLocal.withInitial(() -> { synchronized (MapSafePublication.this) { return new HashMap<>(map); } }); synchronized void write(K key, V value) { map.put(key, value); } V read(K key) { return safeMap.get().get(key); } } 所使用的锁相同的锁,如何安全地从数组中读取?

volatile Object[] array = new Object[size]; array[index] = value; 的结果也是如此,据我目前的理解,这并不构成安全发布存储在参数对象中或由参数对象返回的引用。我错了吗?

java multithreading collections guava immutability
1个回答
1
投票

回答您的第一部分:

Collections.unmodifiableMap()并不构成地图中存储的引用的安全发布。

正确。

通过检查Map.of()的实现...

唯一要检查的地方是Javadoc。如果未描述任何线程安全保证,则没有可靠的保证。可以更改实现以使事情“线程安全”,或删除线程安全。

© www.soinside.com 2019 - 2024. All rights reserved.