Java 并发 - 内联初始化的非最终字段和安全发布

标签 java multithreading concurrency java-memory-model

假设我有以下类(class):

public abstract class Test {
    private List<String> strings = new ArrayList<>();

    // to be called concurrently
    public int getStringsSize() {
        return strings.size();
    }
}

getStringsSize() 是否有可能为 Test 的某些子类抛出 NPE?或者还有什么可能出错?据我所知,对于这种情况,Java 内存模型没有任何保证。

最佳答案

要点是:当子类对象被实例化时, super 构造函数和 super field init 语句将在任何子类代码执行之前执行。参见 herethere了解更多信息。换句话说:在通过 new 创建子类的 client 访问新创建的对象之前,可以保证执行这些 init 语句。

因为我们正在谈论仅存在于父类(super class)中的单个私有(private)字段,所以该方法调用没有机会产生 NPE

除非您有其他方法将字段重置为空。您可以通过为该字段使用 final 关键字来避免这种情况(无论如何这是一个很好的做法:将默认设置为在字段上放置final) .

最后;为了完整性:在子类上执行 new 时,可能会编写失败的父类(super class)/子类代码,因为“某些东西尚未初始化”——就像当你的父类(super class)构造函数调用 的方法时在子类中重写。但这就像:不好的做法(因为它会导致这种奇怪的错误)。所以别想这么做。

关于Java 并发 - 内联初始化的非最终字段和安全发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44700720/

相关文章:

没有同步就不能共享 Scala 不可变集合吗?

c++ - 全局变量构造函数/析构函数是否需要线程保护?

java - 不建议在 ExecutorService 中使用 wait(),notify() 方法

java - 操作超时和连接重置 - 400 并发访问 MySQL

java - 如何在 spring-boot 中完全禁用 swagger-ui?(/swagger-ui.html 应该返回 404)

java - 在 Spring MVC 应用程序中使用 CXF 创建 SOAP 客户端时出错

java - java中终止一个线程有一点问题

java - java中比较器的接口(interface)实现

c++ - C++ 11 触发异步任务并忘记它的方法是什么?

java - 为什么Java AQS队列会向后遍历