4

I was exploring the singleton design pattern, I have developed a class...

public class SingletonObject {
  private static SingletonObject ref;       
  private SingletonObject () { //private constructor
  }     
  public static synchronized SingletonObject getSingletonObject() {
    if (ref == null)
      ref = new SingletonObject();
    return ref;
  } 

  public Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException ();
  }
}

but synchronization is very costly , so I move to new design of eagerly created instance rather than a lazily created one..

public class Singleton {
  private static Singleton uniqueInstance = new Singleton();
  private Singleton() {
  }
  public static Singleton getInstance() {
    return uniqueInstance;
  }
}

But please advise me how the second design is advantage over the previous design..!!

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
dghtr
  • 561
  • 3
  • 6
  • 20
  • 2
    singleton is now generally considered harmful ... – Dapeng Apr 20 '12 at 17:32
  • 4
    @Dapeng Really? Could you expand on this? – Aidanc Apr 20 '12 at 17:33
  • @Dapeng... well I am more focused on my question..!! – dghtr Apr 20 '12 at 17:34
  • but maybe some else could ask the question separate and post the link here? I'm very interested in it as well but know far to much about singletons to actually formulate one. – nuala Apr 20 '12 at 17:48
  • "but synchronization is very costly", this is no longer the case. – Steve Kuo Apr 20 '12 at 17:56
  • 1
    @Dapeng, that's absurd. Bad programming is considered harmful. There's nothing inherently wrong with the singleton pattern, it's used all over the place. – Rick Mangi Apr 20 '12 at 17:59
  • wow, didn't expect that my comment generated so many reply. the problem about singleton is about the testability. since you only have one instance, there is no *sane* way to mock it. life cycle control is also tricky to implement. the final issue, singleton is global variable and anything reachable from it is also considered as global ... – Dapeng Apr 23 '12 at 03:30

6 Answers6

5

Josh Bloch recommends using an enum:

   public enum Foo {
       INSTANCE;
   }

For an explanation, see his Effective Java Reloaded talk at Google I/O 2008.

In summary:

"This approach is functionally equivalent to the public field approach, except that it is more concise, provides the 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."

Amir Afghani
  • 37,814
  • 16
  • 84
  • 124
2

As you stated, the second solution avoids synchronization costs. It is also simpler and cleaner, so easier to read and maintain. It has a little problem though: you miss a final qualifier for private static Singleton uniqueInstance, which means that it may not be guaranteed to be thread safe in a concurrent environment (although in this concrete case I don't think this would cause any tangible problem in real life... but better be on the safe side regarding thread safety). Luckily this is easy to fix.

Its other drawback is that as soon as the class Singleton is referenced, the singleton object is created, even if it is never actually used. This might be a problem if creation is costly. It can be avoided with the Initialization-on-demand Holder idiom.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
1

Your second design is better in that it is a bit more concise and easier to read. Also, as you mentioned, it avoids the cost of synchronizing every time you wish to use the singleton.

One drawback of your second design is that you incur the memory and cpu cost of instantiating the singleton even if you never use it.

Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
  • @Jack..Using this approach, we rely on the JVM to create the unique instance of the Singleton when the class is loaded. The JVM guarantees that the instance will be created before any thread accesses the static uniqueInstance variable, but please could you guide how to improve itnow, could you lpease show by converting my code and implementing your suggestions in it that will be agreat help..!1 – dghtr Apr 20 '12 at 17:41
1

Eager Instantiation vs. Lazy Initialization

Your second design uses eager instantiation instead of lazy initialization. That's not necessarily better or worse, it depends on which is appropriate for your application.

Generally it's better to use lazy initialization if:

  • If there's a chance that your application won't need to create an instance of your class
  • If instantiating your class is expensive, and you'd rather defer the operation till as late as possible

Thread Safety and Performance

One other advantage of your second design is that it's more performant. In a multi-threaded environment, your first design will require each thread to acquire a lock before getting the instance, even after it has already been instantiated. You can get around this by using double-checked locking or the Bill Pugh approach.

Enum Way

An approach that is different than both of your designs is the Enum way, which uses an Enum with a single value. Since Enums can have methods and member variables, you can mimic the kind of behavior that a normal class would have. This is a nice, ironclad way to create a singleton, and is recommended by Joshua Bloch.

Mansoor Siddiqui
  • 20,853
  • 10
  • 48
  • 67
  • Hi Mansoor, thanks a lot, could you please show me the approach of Enum one , that will help to make understanding more clreare..!!thanks – dghtr Apr 20 '12 at 17:47
  • I added more details about the Enum approach in my answer ... hope that helps! The wikipedia page that I linked to also does a good job of summarizing the approach. – Mansoor Siddiqui Apr 20 '12 at 17:59
0

You should also make the variable pointing to your singleton final.

public class Singleton {
    private static final Singleton uniqueInstance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return uniqueInstance;
    }
}

This implementation has the ClassLoader instantiate the instance of the singleton, providing thread safety. An alternative pattern uses an enum, but I personally consider that implementation to be a code smell.

Tim Bender
  • 20,112
  • 2
  • 49
  • 58
  • could you please show the alternative pattern too, ..in my code how it can be improved..!! – dghtr Apr 20 '12 at 17:45
0

Few notes:

  1. Your first example does not work as expected in multi-threaded scenario. Your ref should be volatile variable and double check with locking is required.

  2. Your second example does not have additional synchronization cost. But you can implement Lazy Singleton instead of eager Singleton effectively.

Refer to below SE question for more details:

Why is volatile used in this example of double checked locking

Community
  • 1
  • 1
Ravindra babu
  • 37,698
  • 11
  • 250
  • 211