这类Threadsafe?

2 java concurrency immutability thread-safety


下面的课程线程安全吗?

class ImmutablePossiblyThreadsafeClass<K, V> {

    private final Map<K, V> map;

    public ImmutablePossiblyThreadsafeClass(final Map<K, V> map) {
        this.map = new HashMap<K, V>();

        for (Entry<K, V> entry : map.entrySet()) {
            this.map.put(entry.getKey(), entry.getValue());
        }
    }

    public V get(K key) {
        return this.map.get(key);
    }
}
Run Code Online (Sandbox Code Playgroud)

Pét*_*rök 5

如果这是整个类的定义,即没有其他的setter/modifier方法,那么map本身的用法是线程安全的:

  • 它的初始化和可见性通过声明来保护final,
  • 包含类只有一个getter,没有修饰符方法,
  • 地图的内容是从构造函数参数映射中复制的,因此不能通过外部引用来修改它.

(请注意,这只是指地图的结构 - 地图中的各个元素可能仍然不安全.)

更新

关于在构造期间同时修改构造函数参数没有保护类的声明,我倾向于同意已经指出的其他人(包括@Bozho)

  1. 没有已知的方法来防范这种情况(甚至没有使用ConcurrentHashMap@Grundlefleck建议 - 我检查了源代码及其构造函数只是调用putAll(),这也没有防止这种情况),
  2. 确保构造函数参数未被同时修改是调用者的责任而不是被调用者.事实上,任何人都可以定义处理同时修改的构造函数参数的"正确"行为吗?创建的对象是否应包含参数映射中的原始元素或最新元素?...如果开始考虑这个问题,恕我直言,不难发现唯一一致的解决方案是禁止并发修改构造函数参数,这只能由来电者确保.