Lazy Initialization is a way of improving performance of application. In lazy initialization objects are not initialized until they are needed. This saves the cost of creating objects and wasting memory until they are actually needed. Proxy Objects in Hibernate are good example of lazy initialization. Let’s see lazy initialization when there is no multi-threading.

class SomeClass {
  private Resource resource = null;
  public Resource getResource() {
    if (resource == null)
      resource = new Resource();
    return resource;
  }
}

As you can see above “resource” will be initialized only when it will be needed. But this will not work in multi-threaded environment. Because multiple threads can be at line 5 at the same time and it will create multiple objects. To prevent this we can use synchronized keyword at the method level but creating “synchronized methods” are bad for performance, it cost more. So next thought comes to put synchronized block inside the function. Now code look like below

class SomeClass {
  private Resource resource = null;
  public Resource getResource() {
    if (resource == null) {
      synchronized(SomeClass.class){
        if (resource == null)
          resource = new Resource();
      }
    }
    return resource;
  }
}

Above code seems certainly better. It synchronizes “resource” so at a time only one thread can enter and initialize the resource. This implementation is called “Double checking lock” or DCL. But this is also having one issue with Java Memory Model. That is partially initialized objects can be returned. DCL has been explained very well in Brain Goetz article here. I will summarize it in the following statement.

When JVM executes multiple instructions, it can rearrange instructions such that actual result will not change but performance will increase. So when doing new Resource(), it can first allocate memory for object, return the reference to that memory location into “resource” variable and then it will start initialization of inner fields by calling constructor of “Resource object”. As the reference is returned before the constructor is called, it will result into partially created object which is undesirable because its a multi-threading environment and other threads can start using that reference when they found it “not null”.

This problem is very rare and it does not come on all the platforms because few JVMs actually implement the JMM properly. But we can overcome this issue by scarifying performance optimization which was happening by reordering of instructions. If we declare our lazy initialized objects to be volatile then JVM will not rearrange the order of instructions. Note that all the fields inside resource should also be volatile. If your resource class is some third party class and internal fields are not volatile then there are still chances of partially constructed objects. So this way we can improve more but it is still not fixed fully. After implementing volatile; now code will look like this

class SomeClass {
  private volatile Resource resource = null;
  public Resource getResource() {
    if (resource == null) {
      synchronized(SomeClass.class){
        if (resource == null)
          resource = new Resource();
      }
    }
    return resource;
  }
}

The above solution(partially fixed) works from Java 1.5 or later. Brain Goetz had written another article in which he showed a fully working solution for lazy initialization. But it works only for static fields where there should be only one instance of the field shared across all the objects like “db connection instance”. Here is the JSR-133 which covers DCL issue and introduced “Demand Holder idiom”. I will summaries it here.

Class initialization is inherently thread-safe and if you can have an object initialized on class initialization the object creation too are thread-safe.

So here is the less complicated solution of Lazy Initialization In Multi-threaded environment for static fields.

class SomeClass {

	  public Resource getResource() {
	    return ResourceHolder.instance;
	  }

	  // Resource Holder
	  private static class ResourceHolder{
	         private static final Resource instance = new Resource();
	  }
}

In above example resource will be only be created when getResource is called first time. As the class initialization is thread-safe so resource creation will automatically be thread-safe. But notice that inner class is static so this instance will be static. Static is must here, we can not remove it to support lazy initialization of non-static fields because if we remove “static” from inner class then we can not write “ResourceHolder.instance”. We have to create an object of that and object creation is not thread-safe only class loading is thread safe. This will also work for lazy initialization of singleton class because internally they have static field.

Note that if you have multiple static fields for lazy initialization then you have to create multiple static inner classes.

Here is the lazily initialized thread-safe singleton class

public class MySingletonClass{

   private MySingletonClass(){

   }
   public static MySingletonClass getInstance(){
         return IntiailizationOnDemandClassHolder.instance;
   }

   private static class IntiailizationOnDemandClassHolder{
         private static final MySingletonClass instance = new MySingletonClass();

   }

}

Tom has compared performance of all the approched in his blog.

TECHNICAL APPROACH TOTAL TIME MINUS OVERHEAD PER OPERATION
‘synchronized’ method 858 ms 834 ms 83.4 ns
double-checked locking, ‘volatile’ field 39.27 ms 15.79 ms 1.58 ns
inner-class static init 33.4 ms 9.92 ms 0.99 ns
loop & hashcode overhead 23.48 ms 2.35 ns

This is over 25 times faster on our benchmark!

Above singleton will work fine but still sometimes people want to protect singleton from cloning, reflection and de-serialization & serialization so there will not be more than one objects of a singleton class. My next article will explain that more in detail.

Continue to Safe Singleton

References

Tagged on:                 

3 thoughts on “Lazy Initialization in Multi-threaded Environment

  • Pingback: Safe Singleton | Java and Me

  • February 16, 2015 at 11:31 pm
    Permalink

    Wow! Finally I got a weblog from where I be capable of really
    get helpful facts regarding my study and knowledge.

    Reply
  • May 20, 2015 at 11:52 pm
    Permalink

    We’re a group of volunteers and opening a new scheme in our community.
    Your web site offered us with helpful information to work on. You
    have performed an impressive activity and our whole neighborhood will probably
    be thankful to you.

    Reply

Leave a Reply to Rey Cancel reply

Your email address will not be published.


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>