关于实例变量初始化的线程安全性

我看到这个初始化实例变量的习惯很多

public class Test{ private Long l = 1l; private MyClass mc = new MyClass(); public Test(){} ... } 

但我更愿意

 public class Test{ private Long l; private MyClass mc; public Test(){ l = 1l; mc = new MyClass(); } ... } 

考虑到这些是非最终变量,在线程安全方面,2种方法是等效的还是比另一种更“正确”?

线程安全不是问题,因为这在构造阶段发生,并且两个线程不能构造相同的对象。 好吧,如果你让它从构造函数中逃脱,那么另一个线程可能在构造期间访问该对象,但你真的不应该这样做。 function方面,两个选项是相同的,所以即使存在线程安全问题,它们也会以同样的方式影响。

如果你需要做一些无法在初始化程序中完成的计算,那么第一个选项是初始化声明中的字段并不总是可能的(即使这样,如果你在初始化程序中执行它,你可以保持初始化的构造函数虽然阻止)。 但是,如果任何一种方式都可行,那么它纯粹是一种风格问题,我不认为Java程序员有明显的偏好,所以请选择对你来说更好的方式。

由于您的变量是实例变量,而不是类变量,因此在初始化期间使用任一方法都没有线程安全问题。 如果有一个Java标准推荐的最佳实践,我相信其他人会参与进来。

我认为这是个人偏好和项目编码标准的问题。

只需确保只在一个地方(构造函数或内联)初始化变量。

在构造函数中完成初始化工作后,您可以更好地进行exception处理。

它们都不是线程安全的。 如果线程A构造对象,则线程B可能会或可能不会观察到未完全初始化的Test对象或MyClass对象。 构造函数退出后的可见性保证仅适用于最终字段。

见http://pveentjer.wordpress.com/2007/03/18/immutability-doesnt-guarantee-thread-safety/

在线程安全方面,它们是等效的。 两者都需要执行相同的指令,如果您更喜欢第二个(我根据您的喜好与您达成一致),那么我会使用它。 如果您希望构造函数周围的线程安全,则需要围绕构造函数调用进行同步调用。