What are some recommended approaches to achieving thread-safe lazy initialization? For instance,
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
What are some recommended approaches to achieving thread-safe lazy initialization? For instance,
// Not thread-safe
public Foo getInstance(){
if(INSTANCE == null){
INSTANCE = new Foo();
}
return INSTANCE;
}
If you're using Apache Commons Lang, then you can use one of the variations of ConcurrentInitializer like LazyInitializer.
Example:
You can now safely get Foo (gets initialized only once):
If you're using Google's Guava:
Then call it by
Foo f = fooSupplier.get();
From Suppliers.memoize javadoc:
Put the code in a
synchronized
block with some suitable lock. There are some other highly specialist techniques, but I'd suggest avoiding those unless absolutely necessary.Also you've used SHOUTY case, which tends to indicate a
static
but an instance method. If it is really static, I suggest you make sure it isn't in any way mutable. If it's just an expensive to create static immutable, then class loading is lazy anyway. You may want to move it to a different (possibly nested) class to delay creation to the absolute last possible moment.This is called double checking! Check this http://jeremymanson.blogspot.com/2008/05/double-checked-locking.html
For singletons there is an elegant solution by delegating the task to the JVM code for static initialization.
see
http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom
and this blog post of Crazy Bob Lee
http://blog.crazybob.org/2007/01/lazy-loading-singletons.html
The easiest way is to use a static inner holder class :
If you use lombok in your project, you can use a feature described here.
You just create a field, annotate it with
@Getter(lazy=true)
and add initialization, like this:@Getter(lazy=true) private final Foo instance = new Foo();
You'll have to reference field only with getter (see notes in lombok docs), but in most cases that's what we need.