微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java并发性:final字段在构造函数中初始化是线程安全的吗?

如何解决Java并发性:final字段在构造函数中初始化是线程安全的吗?

正如已经指出的那样,它是绝对线程安全的,并且final由于其内存可见性影响而在这里很重要。

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

  • 从静态初始化程序初始化对象引用;
  • 将对它的引用存储到volatile字段或atomicreference中;
  • 将对它的引用存储到适当构造的对象的最终字段中;要么
  • 将对它的引用存储到由锁适当保护的字段中。

解决方法

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

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常见问题解答

应该提供初始化安全性的新保证。如果正确构造了一个对象(这意味着对该对象的引用在构造期间不会逸出),那么所有看到对该对象的引用的线程也将看到在构造函数中设置的其最终字段的值,而无需同步。

这使我感到困惑,因为aMap的设置是aMap = new HashMap<String,String>();。所以其他线程可以看到这些

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

或不 ?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。