Synchronized blocks in constructors

萝らか妹 提交于 2021-02-07 21:08:33

问题


I have a class with a static var like so

private static Object sMyStaticVar;

if i want to assign a value to this var in the constructor I have code like

if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);

where someRuntimeObject is an object that is not available at the time my class is loaded and therefore prevents me from declaring my static var like the below

private static Object sMyStaticVar = new CustomObject(someRuntimeObject);

my question is, is the initialization of the static var object in the constructor thread safe? My instincts tell me its not and i should synchronise using the non-runtime class type as the lock, like the below

synchronized(MyClass.class)
{
    if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);
}

(as opposed to the runTime type obtained from getClass())

but as my instincts are usually wrong I would be grateful if anyone could shed some light on this for me!


回答1:


If it is static, you should not assign it in the constructor. Make a static initializer method that does that public static synchronized void initialize(someRuntimeObject).

Note the synchronized keyword: it is is the same as synchronizing on MyClass.class




回答2:


You are right, the following is open to race conditions:

if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);

Two threads could check sMyStaticVar at the same time, see null, create two objects, etc...

This means that you need synchronization. You could either synchronize on some existing object (there are multiple choices), or you could create an object just for the prurpose, so that you don't have to share the lock with anyone else, risking unnecessary contention:

private static Object sMyStaticVar;
private static Object sMyStaticVarLock = new Object();

Then, in the constructor:

synchronized(sMyStaticVarLock)
{
    if(sMyStaticVar == null) sMyStaticVar = new CustomObject(someRuntimeObject);
}



回答3:


This syncrhonization is needed, but it's not enough to achieve thread safety.

You also need to ensure visibility of the field's value when you access it. So, you should either declare that field as volatile or add the same synchronization to every access of that field.



来源:https://stackoverflow.com/questions/7993874/synchronized-blocks-in-constructors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!