Java 部分构造对象
如果一个对象在初始化过程中对其他线程可见(在初始化过程中可见,但尚未完成),那么这是否可能?如果是的话,你能举一个简单的例子来证明你的理由吗 这可以通过多种方式实现Java 部分构造对象,java,Java,如果一个对象在初始化过程中对其他线程可见(在初始化过程中可见,但尚未完成),那么这是否可能?如果是的话,你能举一个简单的例子来证明你的理由吗 这可以通过多种方式实现 将对象传递给构造函数中的另一个线程,例如,在构造函数中启动一个线程 您将对象传递给另一个线程,但另一个线程会看到旧的、未初始化的值,因为这些字段不是final或volatile,也不是在锁定或同步的块中访问的。其他字段不保证线程安全 这可以通过多种方式实现 将对象传递给构造函数中的另一个线程,例如,在构造函数中启动一个线程 您将
- 将对象传递给构造函数中的另一个线程,例如,在构造函数中启动一个线程
- 您将对象传递给另一个线程,但另一个线程会看到旧的、未初始化的值,因为这些字段不是final或volatile,也不是在锁定或同步的块中访问的。其他字段不保证线程安全
- 将对象传递给构造函数中的另一个线程,例如,在构造函数中启动一个线程
- 您将对象传递给另一个线程,但另一个线程会看到旧的、未初始化的值,因为这些字段不是final或volatile,也不是在锁定或同步的块中访问的。其他字段不保证线程安全
- 这可以通过多种方式实现
public class Holder { public static File f; }
在线程A的某个地方,您可以
Holder.f=新文件(“路径”)代码>和线程B中的其他地方,您可以文件xxf=Holder.f
并继续使用它。即使您阅读了对Holder.f
的引用,也不能保证文件
实例的任何字段都将处于任何已定义状态。您可以读取所有的空值(零、假值,具体取决于类型),甚至可以读取非空值和空值的任意错误组合。最好的例子是众所周知的破坏双重检查锁定习惯用法。我将仅从中摘录与此论点相关的部分。以这个代码为例:
public class Holder { public static File f; }
在线程A的某个地方,您可以Holder.f=新文件(“路径”)代码>和线程B中的其他地方,您可以文件xxf=Holder.f
并继续使用它。即使您阅读了对Holder.f
的引用,也不能保证文件
实例的任何字段都将处于任何已定义状态。您可以读取所有空值(零、假值,具体取决于类型),甚至可以读取非空值和空值的任何错误组合。我猜它是Hi的重复,我猜它是Hi的重复!谢谢你的回答。我对volatile变量有疑问,比如:volatile Pool=newpool();如果池构造函数在初始化过程中抛出异常,则池指向何处,如果池构造函数抛出异常,池引用将保持不变——它不会引用部分构造的对象。@ ysavIT是否意味着它仍然指向先前分配的实例?是的,确切地,还是空的,如果引用以前为空。如果您将this
传递到构造函数中的某个位置并引发异常,则将有一个部分构造的对象。;)你好谢谢你的回答。我对volatile变量有疑问,比如:volatile Pool=newpool();如果池构造函数在初始化过程中抛出异常,则池指向何处,如果池构造函数抛出异常,池引用将保持不变——它不会引用部分构造的对象。@ ysavIT是否意味着它仍然指向先前分配的实例?是的,确切地,还是空的,如果引用以前为空。如果您将this
传递到构造函数中的某个位置并引发异常,则将有一个部分构造的对象。;)如果一个对象的构造函数设置了一个final
字段来引用一个新构造的、新编写的、从未通过任何其他方式公开过的持有者;对最终
字段引用的存储是否能保证对对象内项目的所有写入都已完成?引用JLS 17.5:“当另一个线程看到该对象时,该线程将始终看到该对象的final
字段的正确构造版本。它还将看到那些final
字段引用的任何对象或数组的版本,这些字段至少与final
字段一样是最新的。“我想这正是你所问的。谢谢。因此,如果创建对象的唯一目的是将对它的引用放置到最终字段中,并且如果此后它将永远不会暴露于任何会修改它的内容,那么对象本身就不需要担心它的任何字段是否为最终
。知道这个很有用。谢谢。如果一个对象的构造函数设置了一个final
字段来引用一个新构造的、新编写的、从未通过任何其他方式公开过的持有者;对最终
字段引用的存储是否能保证对对象内项目的所有写入都已完成?引用JLS 17.5:“当另一个线程看到该对象时,该线程将始终看到该对象的final
字段的正确构造版本。它还将看到那些final
字段引用的任何对象或数组的版本,这些字段至少与final
字段一样是最新的。“我想这正是你所问的。谢谢。因此,如果创建对象的唯一目的是将对它的引用放置到最终字段中,并且如果此后它将永远不会暴露于任何会修改它的内容,那么对象本身就不需要担心它的任何字段是否为最终
。知道这个很有用。谢谢