Wiki Markup |
---|
Instead of initializing a member object using a constructor, sometimes a technique called _lazy initialization_ can isbe used to defer the construction of the member object until an instance is actually required. Lazy initialization also helps in breaking harmful circularities in class and instance initialization, and performing other optimizations \[[Bloch 05|AA. Java References#Bloch 05]\]. |
A class or an instance method is used for lazy initialization, depending on whether the member object is static
or not. The method checks whether the instance has already been created and if not, creates it. If the instance already exists, it simply returns it. This is shown below:
Code Block |
---|
|
// Correct single threaded version using lazy initialization
final class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null) {
helper = new Helper();
}
return helper;
}
// ...
}
|
In a multithreading scenariomultithreaded application, the initialization must be synchronized so that two or more multiple threads do not create multiple extraneous instances of the member object. The code shown below is safe for execution in a multithreaded environment, albeit slower than the previous, single threaded code example. :
Code Block |
---|
|
// Correct multithreaded version using synchronization
final class Foo {
private Helper helper = null;
public synchronized Helper getHelper() {
if (helper == null) {
helper = new Helper();
}
return helper;
}
// ...
}
|
The double checked locking (DCL) idiom is used to provide lazy initialization in multithreaded code. In a multithreading scenario, traditional lazy initialization is supplemented by reducing the cost of synchronization for each method access by limiting the synchronization to the case where the instance is required to be created and forgoing it when retrieving an already created instance.
...