Java 并发数 : is final field (initialized in constructor) thread-safe?

标签 java concurrency java-memory-model

谁能告诉我这个类是否是线程安全的?

class Foo {

    private final Map<String,String> aMap;

    public Foo() {
        aMap = new HashMap<String, String>();
        aMap.put("1", "a");
        aMap.put("2", "b");
        aMap.put("3", "c");
    }

    public String get(String key) {
        return aMap.get(key);
    }

}

编辑:我没有澄清问题是我的错。根据JMM FAQ :

A new guarantee of initialization safety should be provided. If an object is properly constructed (which means that references to it do not escape during construction), then all threads which see a reference to that object will also see the values for its final fields that were set in the constructor, without the need for synchronization.

这让我感到困惑,因为 aMap 的集合是 aMap = new HashMap<String, String>(); .这样其他线程就可以看到这些

aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");

还是不是?

编辑:我找到了这个 question这完全符合我的问题

最佳答案

正如已经指出的那样,它绝对是线程安全的,final 在这里很重要,因为它具有内存可见性效果。

final 的存在保证其他线程在构造函数完成后可以在映射中看到值,而无需任何外部同步。如果没有 final,就不能在所有情况下都得到保证,并且在使新构造的对象对其他线程可用时,您需要使用安全发布习语,即(来自 Java Concurrency in Practice ) :

  • Initializing an object reference from a static initializer;
  • Storing a reference to it into a volatile field or AtomicReference;
  • Storing a reference to it into a final field of a properly constructed object; or
  • Storing a reference to it into a field that is properly guarded by a lock.

关于Java 并发数 : is final field (initialized in constructor) thread-safe?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6457109/

相关文章:

java - 如何在特定时间间隔调用作为 Web 应用程序部署到 Apache Tomcat 服务器的 Java 方法?

ios - 为什么 NSOperation 在上一个操作完成之前就开始了?

java - 电子商务应用程序设计(例如 : Amazon/ebay/flipkart ): Concurrency issues handling

node.js - 如何重试mongodb事务?

java - 在 Java 中覆盖(归零)字符串密码

java - Java 是否保证当前同步的对象不会被垃圾回收?

java - 如何从 Android 应用程序打开 Facebook 应用程序上的个人资料

java - 如何在不启动新的 jvm 进程的情况下从 ant 调用 maven?

java - 使用从 .jar 导入的 MigLayout

java - Guava 中使用的无锁懒加载模式真的是线程安全的吗?