简体   繁体   中英

Is initialized non final static variables are thread safe?

Assume, I have a private non final static variable, and initialized in the static block, and it is not modified after initialization and has no methods to modify the variable. Is it threadsafe?

class Test
{
     private static int value = 10;

     public static int getValue()
     {
        return value;
     }
 }

I just wanted to know what guarantee JVM provides with non final static variables with no methods to modify the variable in terms of thread safety, where multiple threads try to read the data.

The procedure for initializing a class ( JLS 11.4.2 ) states that that initialization is performed while holding a lock. I think that this implies that any thread that refers to the statics after initialization has completed will see the fully initialized state.

You might get into trouble if you had a situation where the static initialization of one class created and started a thread that could observe the static variables of another class before they latter's static initialization completed. In that case, it may not be possible to guarantee that the thread will see the initialized state.


The other think to note is that we are only talking about the values in the static variables here. If those variables refer to mutable objects or arrays, and those objects / arrays are mutated, then your code is not automatically thread-safe.

This illustrates a larger point. You can't actually talk about the thread-safety of variables in isolation. The accepted definition of thread-safety is that the introduction of threading does not result in incorrect behaviour of something. Variables don't have behaviour. Behaviour is an application level thing, though it is sometimes meaningful to consider the behaviour of a part of an application; eg some classes or methods in a particular application context.


Reading between the lines ... you seem to be trying to avoid the "overheads" of synchronization in your usage of statics. That is all well and good ... but the thread-safety, static initialization and the memory model are all some of the most difficult / hard to understand parts of the Java language. Many really smart people have (in the past) tried and failed when implementing "clever" or "efficient" ways of reducing synchronization overheads.

My advice: don't try to be too smart. Keep it simple. The synchronization overheads are not large enough (IMO) to risk introducing "heisenbugs" into your code-base.

And finally, it is generally accepted that static variables, and especially mutable static variables are bad OO design. I would advise you to consider revising your design to eliminate them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM