Reputation: 241
The classic of writing a singleton in java is like this:
public class SingletonObject
{
private SingletonObject()
{
}
public static SingletonObject getSingletonObject()
{
if (ref == null)
// it's ok, we can call this constructor
ref = new SingletonObject();
return ref;
}
private static SingletonObject ref;
}
and we can add synchronized keyword if we need it to run in multithreaded cases.
But I prefer to write it as:
public class SingletonObject
{
private SingletonObject()
{
// no code req'd
}
public static SingletonObject getSingletonObject()
{
return ref;
}
private static SingletonObject ref = new SingletonObject();
}
which I think is more concise, but strangely I didn't see any sample code written in this way, is there any bad effects if I wrote my code in this way?
Upvotes: 12
Views: 36240
Reputation: 570365
In the second form, your singleton is eagerly loaded and this is actually the preferred form (and the first one isn't thread-safe as you mentioned it yourself). Eager loading is not a bad thing for production code but there are contexts where you might want to lazy load your singletons, as discussed by the author of Guice, Bob Lee, in Lazy Loading Singletons that I'm quoting below:
First, why would you want to lazy load a singleton? In production, you typically want to eagerly load all your singletons so you catch errors early and take any performance hit up front, but in tests and during development, you only want to load what you absolutely need so as not to waste time.
Before Java 1.5, I lazy loaded singletons using plain old synchronization, simple but effective:
static Singleton instance; public static synchronized Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; }
Changes to the memory model in 1.5 enabled the infamous Double-Checked Locking (DCL) idiom. To implement DCL, you check a
volatile
field in the common path and only synchronize when necessary:static volatile Singleton instance; public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) instance = new Singleton(); } } return instance; }
But
volatile
isn't that much faster thansynchronized
,synchronized
is pretty fast nowadays, and DCL requires more code, so even after 1.5 came out, I continued using plain old synchronization.Imagine my surprise today when Jeremy Manson pointed me to the Initialization on Demand Holder (IODH) idiom which requires very little code and has zero synchronization overhead. Zero, as in even faster than
volatile
. IODH requires the same number of lines of code as plain old synchronization, and it's faster than DCL!IODH utilizes lazy class initialization. The JVM won't execute a class's static initializer until you actually touch something in the class. This applies to static nested classes, too. In the following example, the JLS guarantees the JVM will not initialize
instance
until someone callsgetInstance()
:static class SingletonHolder { static Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; }
[...]
Update: Credit where credit is due, Effective Java (copyright 2001) detailed this pattern under item 48. It goes on to point out that you still have to use synchronization or DCL in non-static contexts.
I also switched singleton handling in my framework from synchronization to DCL and saw another 10% performance boost (compared to before I started using cglib's fast reflection). I only used one thread in my micro-benchmark, so the boost to concurrency could be even greater given that I replaced a heavily contended lock with a relatively fine grained volatile field access.
Note that Joshua Bloch now recommends (since Effective Java, 2nd ed) to implement singletons using a single-element enum
as pointed out by Jonik.
Upvotes: 18
Reputation: 11
I am declaring private constructor and static block so the purpose of static block is it will execute only once and inside a static block I am creating an object so constructor will be invoked only once.
class Demo {
static Demo d=null;
static {
d=new Demo();
}
private Demo(){
System.out.println("Private Constructor");
}
void add(){
System.out.println("Hello I am Non-Static");
}
static Demo getInstance(){
return d;
}
}
Upvotes: 0
Reputation: 77
// Lazy loading enabled as well as thread safe
class Singleton {
private static class SingletonHolder {
public static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
Upvotes: 0
Reputation: 3540
Different ways to implement singleton pattern in java is as follows
public class SingletonClass {
private SingletonClass= null;
public static SingletonClass getInstance() {
if(SingletonClass != null) {
SingletonClass = new SingletonClass();
}
}
}
This is not thread safe. The following are thread safe
implementation of singleton design pattern
1. Draconian synchronization
private static YourObject instance;
public static synchronized YourObject getInstance() {
if (instance == null) {
instance = new YourObject();
}
return instance;
}
2.Double check synchronization
private static final Object lock = new Object();
private static volatile YourObject instance;
public static YourObject getInstance() {
YourObject r = instance;
if (r == null) {
synchronized (lock) { // While we were waiting for the lock, another
r = instance; // thread may have instantiated the object.
if (r == null) {
r = new YourObject();
instance = r;
}
}
}
return r;
}
3. Initialization-on-demand holder idiom
public class Something {
private Something() {}
private static class LazyHolder {
static final Something INSTANCE = new Something();
}
public static Something getInstance() {
return LazyHolder.INSTANCE;
}
}
4. Other one is using enum
public enum Singleton {
SINGLE;
public void myMethod(){
}
}
Upvotes: 0
Reputation: 11
the second way will solve multi-threading issue but will always create the Singleton even when you don't need it. The best way to do it is to create a Nested class.
public class singleton
{
private singleton()
{
System.out.println("I'am called only when it's needed");
}
static class Nested
{
Nested() {}
private static final singleton instance = new singleton();
}
public static singleton getInstance()
{
return Nested.instance;
}
public static void main(String [] args)
{
singleton.getInstance();
}
}
Upvotes: 1
Reputation: 555
The best way to write a singleton class is given below .Please try it
public final class SingeltonTest {
/**
* @param args
* @return
*/
private static SingeltonTest instance = null;
private SingeltonTest() {
System.out.println("Rahul Tripathi");
}
public static SingeltonTest getInstance() {
if (instance == null) {
synchronized (SingeltonTest.class) {
if (instance == null)
instance == new SingeltonTest();
}
}
return instance;
}
}
Upvotes: 0
Reputation: 81761
Well, in the latter case the singleton object gets created before it is ever needed, but in most cases that's probably not horribly bad.
By the way, Joshua Bloch recommends (in Effective Java, 2nd ed, item 3) implementing singletons using a single-element enum:
public enum SingletonObject {
INSTANCE;
}
He gives the following justification:
[...] it is more concise, provides serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. While this approach has yet to be widely adopted, a single-element enum type is the best way to implement a singleton.
Upvotes: 10
Reputation: 33092
I think your problem is that you're mixing singleton and lazy initialization. A singleton can be implemented with different initialization strategies:
All these approaches are discussed in Effective Java 2nd Item 71: Use lazy initialization judiciously.
Upvotes: 2
Reputation: 1779
I agree with Anon, and in the case where I always want to instantiate the singleton I would use
public class SingletonObject
{
public static SingletonObject REF = new SingletonObject();
private SingletonObject()
{
// no code req'd
}
}
Upvotes: -2
Reputation: 1500735
I would say the latter code is the more standard pattern, actually. Your first version isn't thread-safe. Ways of making it thread-safe include synchronizing on every access, or very carefully making it use double-checked locking (which is safe as of the Java 5 memory model, so long as you get it right).
Note that due to classes being initialized lazily, your latter code would still only create an object unnecessarily if you called static methods on the class without wanting to create the instance.
There's a pattern using a nested class to do the initialization which can make this lazier, but personally the second form almost always does well enough for me on its own.
There are more details of this in Effective Java, but I don't have it with me to find the item number, I'm afraid.
Upvotes: 5
Reputation: 59983
The difference between your code and the "sample code" is that your singleton is instantiated when the class is loaded, while in the "sample" version, it is not instantiated until it is actually needed.
Upvotes: 18