根据Java内存模型,读者线程可以看到部分初始化对象的哪个字段值?

时间:2017-08-22 10:57:43

标签: java concurrency jvm java-memory-model

更具体地说,假设对象被部分初始化并且对象的构造函数将字段x初始化为null,那么读取此部分初始化对象的其他一些线程是否可以看到除null之外的任何其他值?

如果我理解正确,那么Java内存模型本身并不能保证在这种情况下该值始终为null。问题是:考虑CPU缓存和JVM内存架构,是否应合理预期该值可能不为空?

2 个答案:

答案 0 :(得分:2)

是的,这是可能的 - 不能保证一个线程在构造函数中初始化的对象将被另一个线程正确读取。 Java内存模型允许编译器在构造函数中重新排序语句,因为重新排序不会影响初始化完成时对象的状态。

另一个线程可以在对象在内存中分配之后但在构造函数完成之前获取对该对象的引用,并且可以读取未初始化的值。

您需要使用synchronized关键字或使用同步集合来保护对此类变量的访问。

请参阅:Java Memory Model

答案 1 :(得分:1)

默认情况下,引用成员变量初始化为null。如果构造函数已将字段设置为非空值,则其他线程可以看到null或非null值。但是如果构造函数也将值设置为null(在一个简单的场景中似乎是多余的),那么其他线程也不可能看到除null之外的任何值(该字段所具有的唯一值为null,因此存在没有看到任何其他价值的问题)