开发者

On the thread safety of instance variable initialization

I see this idiom of initializing instance variables quite a开发者_如何学Go bit

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

    public Test(){}
    ...
 }

But I would prefer

public class Test{
    private Long l;
    private MyClass mc;

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

Considering that these are non-final variables, are the 2 approaches equivalent or is one "more" correct than the other in terms of thread safety?


Thread safety isn't an issue because this happens at construction phase, and two threads cannot be constructing the same object. Well, if you let this escape from the constructor, it might be possible for another thread to access the object during construction, but you really shouldn't do that. Functionality-wise, the two options are the same, so even if there were thread-safety issues, they would affect both the same way.

The first option, of initializing the fields at their declaration, is not always possible if you need to do some computation that cannot be done in an initializer (even then, you can keep the initialization out of the constructor if you do it in an initializer block, though). But if either way is possible, then it's purely a style issue, and I don't think there is a clear preference among Java programmers, so go with whichever seems better to you.


since your variables are instance variables, not class variables, you don't have a thread safety issue during initialization using either method. I'm sure others will chime in if there's a Java-standard-recommended best practice.


I think it's the matter of personal preference and your project coding standards.

Just make sure you only initialize variables in one place ( either constructor, or inline ).

Having initialization work done in the constructor gives you a better place for exception handling.


They are both not thread-safe. If thread A constructs the object, then thread B may or may not observer an incompletely initialized Test object or MyClass object. The visibility guarantees after a constructor exits only apply to final fields.

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


In terms of thread safety, they are equivalent. Both will need to execute the same instructions, and if you prefer the second (which I agree with you in your preference) then I would use that. If you want thread safety around a constructor, you would need a synchronized call around the constructor call.


I am not sure if this was answered earlier. But, I have a doubt on the following scenario:

I am trying to create a @Component class where in, I have an instance variable. Now, I want to create a new object of the instance variable for each request. I am not sure which one is the right way to do it?

**Option 1:**
@Component
public class ClassA {

private ClassB classB = new ClassB();

public ClassB create(){
    return classB;
 }
}

**Option 2:**
@Component
public class ClassA {

private ClassB classB = null;

public ClassB create(){
    classB = new ClassB();
    return classB;
 }
}

**Option 3:**
@Component
public class ClassA {

public ClassB create(){
    ClassB classB = new ClassB();
    return classB;
 }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜