已初始化对象的 Java 线程安全

标签 java concurrency thread-safety

考虑下面的类:

public class MyClass
{
    private MyObject obj;

    public MyClass()
    {
        obj = new MyObject();
    }

    public void methodCalledByOtherThreads()
    {
        obj.doStuff();
    }
}

由于 obj 是在一个线程上创建并从另一个线程访问的,因此当调用 methodCalledByOtherThread 时 obj 是否可以为 null?如果是这样,将 obj 声明为 volatile 是否是解决此问题的最佳方法?将 obj 声明为 Final 会有什么不同吗?

编辑: 为了清楚起见,我认为我的主要问题是: 其他线程是否可以看到 obj 已被某个主线程初始化,或者 obj 是否已过时(null)?

最佳答案

要使 methodCalledByOtherThreads 被另一个线程调用并导致问题,该线程必须获取对 MyClass 对象的引用,该对象的 obj 字段未初始化,即。构造函数尚未返回。

如果您从构造函数中泄漏了 this 引用,则这是可能的。例如

public MyClass()
{
    SomeClass.leak(this); 
    obj = new MyObject();
}

如果 SomeClass.leak() 方法启动一个单独的线程,在 this 引用上调用 methodCalledByOtherThreads(),那么您将得到问题,但无论 volatile 如何,这都是事实。

由于您没有我上面描述的内容,因此您的代码没问题。

关于已初始化对象的 Java 线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20810210/

相关文章:

c++ - 可连接的 std::thread 不自动连接的原因是什么?

java - 同步代码块

java - 我如何提倡拆分整数?

java - java 中相当于 C# 的 Monitor 类是什么?

c# - 最简单的并发模式

android - 如何在 Android 中下载文件并显示进度?

java - 静态方法中的类实例是线程安全的

java - newKieSession 是线程安全的吗?

java - Hibernate 连接两个表

java - Hibernate saveOrUpdate 方法会删除 child 吗?