I am going through Java Memory Model video presentation and author is saying it is better to use Static Lazy Initialization
compared to Lazy Initialization
and I do not clear understand what he wants to say.
I wanted to reach to community and would appreciate if someone can explain difference between Static Lazy Initialization
and Lazy Initialization
with simple java code example.
Well both implementations can be static so that is the first misunderstanding. The presenter in this video is explaining how you can exploit the thread-safety of class initialization.
Class initialization is inherently thread-safe and if you can have an object initialized on class initialization the object creation too are thread-safe.
Here is an example of a thread-safe statically initialized object
public class MySingletonClass{
private MySingletonClass(){
}
public static MySingletonClass getInstance(){
return IntiailizationOnDemandClassholder.instance;
}
private static class IntiailizationOnDemandClassHolder{
private static final MySingletonClass instance = new MySingletonClass();
}
}
What is important to know here, MySingletonClass instance variable will never be created and or initialized until getInstance()
is invoked. And again since class initialization is thread-safe the instance
variable of IntiailizationOnDemandClassholder
will be loaded safely, once and is visible to all threads.
To answer your edit depends on your other type of implementation. If you want to do double-checked-locking your instance variable would need to be volatile. If you do not want DCL then you will need to synchronize access each time to your variable. Here are the two examples:
public class DCLLazySingleton{
private static volatile DCLLazySingleton instance;
public static DCLLazySingleton getInstace(){
if(instance == null){
synchronized(DCLLazySingleton.class){
if(instance == null)
instance=new DCLLazySingleton();
}
}
return instance;
}
and
public class ThreadSafeLazySingleton{
private static ThreadSafeLazySingleton instance;
public static ThreadSafeLazySingleton getInstance(){
synchronized(ThreadSafeLazySingleton.class){
if(instance == null){
instance = new ThreadSafeLazySingleton();
}
return instance;
}
}
The last example requires a lock acquisition on every request of the instance. The second example requires a volatile-read on each access (may be cheap or not, depends on the CPU).
The first example will always lock once regardless of the CPU. Not only that but each read will be a normal without any need to worry about thread-safety. I personally like the first example I have listed.