Hi,
I came across the Initialize-On-Demand Holder Class idiom in this article by Brian Goetz:
http://www-128.ibm.com/developerworks/java/library/j-jtp03304/
It seems that this would be a good way to implement a thread-safe lazy-initialized Singleton. My first question is "Does this work Ok?"
public class S {
private S() {}
private static class SHolder { private static S s = new S();}
public static S getInstance() { return SHolder.s; }
}
My second question is that if the above is Ok, why do I need the SHolder static inner class to ensure that the S is instantiated lazily (i.e. not until getIntance() is called)?
Why can't I just have:
public class S {
private S() {}
private static S s = new S();
public static S getInstance() { return s; }
}
In my tests (which I realize might not be proving anything), S s = new S(); does not seem to get called until S.getInstance() is called by the client.
Thanks, Jeff.
-
Initialize-On-Demand Holder Class and Singletons (6 messages)
- Posted by: Jeff Reid
- Posted on: July 20 2005 11:59 EDT
Threaded Messages (6)
- Reason for inner class by Jonathan Rupp on July 20 2005 17:37 EDT
- Initialize-On-Demand Holder Class and Singletons by Jeff Reid on July 22 2005 10:35 EDT
- Initialize-On-Demand Holder Class and Singletons by Time PassX on July 27 2005 09:07 EDT
- Initialize-On-Demand Holder Class and Singletons by Stefan Zobel on July 27 2005 17:42 EDT
- Re: Initialize-On-Demand Holder Class and Singletons by Alireza Shokoohi-Fateh on September 08 2008 11:47 EDT
- Re: Initialize-On-Demand Holder Class and Singletons by Matt Butler on January 06 2009 07:59 EST
-
Reason for inner class[ Go to top ]
- Posted by: Jonathan Rupp
- Posted on: July 20 2005 17:37 EDT
- in response to Jeff Reid
The reason you need the inner class to hold the instance is if you have other static methods you want to be able to call without creating the singleton instance.
Static members are created when the class is first used, so calling another static method causes all static data (including the instance variable) to be initialized. By putting it in an inner class, only when the inner class is first referenced (which should only be during calls to the outer class's getInstance()) does the instance get created.
Basically the static inner class is slightly more lazy, but you'll only notice the difference if there are other static methods on your singleton class that are called before getInstance(). In general, I'd say it's bad practice to do that (static methods other than getInstance() on a singleton), but I guess some people must do that. -
Initialize-On-Demand Holder Class and Singletons[ Go to top ]
- Posted by: Jeff Reid
- Posted on: July 22 2005 10:35 EDT
- in response to Jeff Reid
Thanks. -
Initialize-On-Demand Holder Class and Singletons[ Go to top ]
- Posted by: Time PassX
- Posted on: July 27 2005 09:07 EDT
- in response to Jeff Reid
Why not.
public class S {
private S() {}
private static S s;
public static S getInstance() {
if(s == null){
s = new S();
}
return s;
}
} -
Initialize-On-Demand Holder Class and Singletons[ Go to top ]
- Posted by: Stefan Zobel
- Posted on: July 27 2005 17:42 EDT
- in response to Time PassX
Why not.public class S { private S() {} private static S s; public static S getInstance() { if(s == null){ s = new S(); } return s; }}
Because, it's not thread-safe ;-)
Best regards,
Stefan -
Re: Initialize-On-Demand Holder Class and Singletons[ Go to top ]
- Posted by: Alireza Shokoohi-Fateh
- Posted on: September 08 2008 11:47 EDT
- in response to Jeff Reid
We can also create a Singleton using Double-checked locking Pattern like this: public class S { private S() {} private static S s; public static S getInstance() { if (s == null) { synchronized(S.class) { if (s == null) s = new S(); } } } } In this case we have achieved all the goals that we were looking for. This pattern has some deficiencies (http://www.ibm.com/developerworks/java/library/j-dcl.html) but if you know your needs can be a good substitution for inner class on implementing initializing on demand for Singleton design pattern. Rgds Ali -
Re: Initialize-On-Demand Holder Class and Singletons[ Go to top ]
- Posted by: Matt Butler
- Posted on: January 06 2009 07:59 EST
- in response to Alireza Shokoohi-Fateh
We can also create a Singleton using Double-checked locking Pattern like this:
The main deficiency of the code you have supplied is that it may not be thread-safe. For clarity, the article you reference was written in 2002. It's worth noting that this is prior to the inclusion of JSR 133 in JDK 1.5. The following articles, referred to by the OP, cover the problems with the Java Memory Model and what this means in a post JSR-133 world. http://www.ibm.com/developerworks/java/library/j-jtp02244.html http://www.ibm.com/developerworks/library/j-jtp03304/ The second link shows a truly thread-safe implementation of the double checked locking idiom, along with the (possibly) more performant (according to statement the article) implementation that is the subject of this thread as raised by the OP. Best Regards, Mathew Butler
public class S {
private S() {}
private static S s;
public static S getInstance() {
if (s == null) {
synchronized(S.class) {
if (s == null) s = new S();
}
}
}
}
In this case we have achieved all the goals that we were looking for. This pattern has some deficiencies (http://www.ibm.com/developerworks/java/library/j-dcl.html) but if you know your needs can be a good substitution for inner class on implementing initializing on demand for Singleton design pattern.