Data AccessCore JavaApp FrameworksViewTestingBuildingDeploymentDev ToolsSecurityOpinions

Monday, June 15, 2009

Using Static Helper Classes - Java Memory and the Initialization on Demand Holder Idiom

A recent discussion about design patterns and data delegator classes was brought up recently in the tomcat-users mailing list. It is common to find that many web applications use several delegate classes providing access to some data source. Delegate classes are often implemented using the singleton-design pattern, which proposes that at any time there can only be one instance of a singleton (object) created by the JVM.

Theoretically, questions come into mind concerning the governance surrounding instantiation and synchronization of these singleton classes, especially in a multi-threaded environment.

In this post, we'll go over some approaches posted in the thread and provide a best option.

  • Static Initizialization
  • Double Checked Locking (later only on post 1.5 jvm)
  • Initialize-On-Demand Holder Class Idiom (MOST PREFERRED)


Static Initialization
class BeanBag {
private static final SomeBean someBean = new SomeBean();
private static final AnotherBean anotherBean = new AnotherBean();

public static SomeBean getSomeBean() { return someBean; }
public static AnotherBean getAnotherBean() { return anotherBean; }
}

The initialization happens at the loading time of the class but there is no guarantee to be synchronized. The static class property someBean will be available at first call to getSomeBean(). This works 99% of the time, I have never had a problem with it.

Double Lock Checking
class BeanBag {
private static volatile SomeBean someBean = null;

public static SomeBean getSomeBean() {
if (someBean==null){
synchronized(BeanBag.class){
if (someBean==null){
someBean = new SomeBean();
}
}
}
return someBean;
}
}

The difference here, is the singleton instance is not actually instantiated until the getSomeBean() method is called. This provides a more lazy instantiation paradigm if needed. Here we can synchronize the block when SomeBean is instantiated.

Initialize-On-Demand Holder Class Idiom
class BeanBag {
//Inner Class
private static class BeanBagHolder {
public static SomeBean someBean = new SomeBean();
}

public static Something getInstance() {
return BeanBagHolder.someBean;
}
}

This idiom derives its thread safety from the fact that operations that are part of class initialization, which is guaranteed by the JVM. It derives its lazy initialization from the fact that the inner class is not loaded until some thread references one of its fields or methods. This provides the best of both options and guaranteed to be thread-safe by the JVM.

The last option is the most preferred and this article goes into greater detail about Java Memory Model.

3 comments: