BlogX  XML

« December 2009
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today
Links: AMX | diglloyd.com

All | Personal | Sun
20070326 Monday March 26, 2007

An improvement on the “Holder” thread-safety initialization idiom

I’ve been finding many thread-safety issues in the GlassFish source base in the past several months, mostly in the admin code. Many of them involve singleton objects, typically obtained via a getInstance() method. If loading of the class implies immediate use of its singleton instance, and it doesn’t require any arguments to be created, the most efficient (and thread-safe) approach is simply to initialize the instance in a static variable as follows:

// Listing 1
public class Resource {
  private static final Resource _Instance = new Resource();
  public Resource getInstance() {
    return _Instance;
}

For more complex cases, I’ve begun to consider using the "Holder" idiom as described on page 348 of Java Concurrency in Practice. This idiom can be helpful when it is desirable to perform lazy initialization of a resource that might or might not be used. Java Concurrency provides the following code example:

// Listing 2 (prefer Listing 1 above if appropriate)
public class ResourceFactory {
  private static class ResourceHolder {
    public static Resource resource = new Resource();
  }

  public static Resource getResource() {
    return ResourceHolder.resource; 
  }
}

The above idiom has the desirable property of avoiding initialization of a Resource until it is actually needed; the Java Virtual Machine won’t load the ResourceHolder class until it is actually accessed. Because static variables are always guaranteed to be initialized in a thread-safe manner, thread safety is not an issue. This approach might be useful in a class that has multiple objects to initialize as needed and/or if there is a runtime decision to be made based on parameters.

The solution in Listing 2 is good —but the implementation has several questionable issues:

  1. The class ResourceHolder solves one thread safety issue with a dubious declaration, namely that the variable resource is not final, and therefore could be changed to refer to a different instance of Resource—a thread safety issue.
  2. The class ResourceHolder is non-final and it can be constructed as well. There is no legitimate argument for ResourceHolder to ever be a superclass, or to allow an instance of it to be constructed.
  3. It's dubious that a Factory class (ResourceFactory) should be non-final, and thus able to be subclassed. It’s also dubious to allow an instance of it to be constructed.

The example is self-documenting and unambiguous when improved as follows (changes in red):

// Listing 3
public final class ResourceFactory {
    private ResourceFactory() {/*disallow instantiation*/}

    private static final class ResourceHolder {
    	private ResourceHolder() {/*disallow instantiation*/}
        public static final Resource resource = new Resource();
    }

    public static Resource getResource() {
        return ResourceHolder.resource;
    }
}

 

Posted by llc ( Mar 26 2007, 03:28:19 PM PDT ) Permalink Comments [0]

Trackback URL: http://blogs.sun.com/lchambers/entry/h1_an_improvement_on_the
Comments:

Post a Comment:

Name:
E-Mail:
URL:

Your Comment:

HTML Syntax: NOT allowed