18

I had an interview recently and he asked me about Singleton Design Patterns about how are they implemented and I told him that using static variables and static methods we can implement Singleton Design Patterns.

He seems to be half satisfied with the answer but I want to know

  1. How many different ways we can implement Singleton Design Pattern in Java ?
  2. What is the scope of Singleton Object and how does it actually work inside JVM ? I know we would always have one instance of Singleton Object but what is the actual scope of that object, is it in JVM or if there are multiple application running than it's scope is per context basis inside the JVM, I was really stumped at this and was unable to give satisfying explanation ?
  3. Lastly he asked if it is possible to used Singleton Object with Clusters with explanation and is there any way to have Spring not implement Singleton Design Pattern when we make a call to Bean Factory to get the objects ?

Any inputs would be highly appreciated about Singleton and what are the main things to keep in mind while dealing with Singletons ?

Thanks.

Ravindra babu
  • 37,698
  • 11
  • 250
  • 211
Rachel
  • 100,387
  • 116
  • 269
  • 365
  • I think the reason he was half satisfied is that the point of a singleton is to **replace** a class full of static methods with one full of instance methods, and a single instance stored in a static field. – Kirk Woll Aug 07 '10 at 00:14
  • @Kirk Woll - Can you elaborate on the explanation, I want to understand it better. – Rachel Aug 07 '10 at 00:16
  • 6
    Let's say you start with a class with only static methods. If you want to convert this into a singleton, you will remove the **static** modifier from all your methods. Also, you will add a static field whose type is the same as your class to hold the solitary instance. So my point is that static methods and singletons are two mutually exclusive solutions to the same problem. Therefore, suggesting the use of static methods is not really correct for implementing a singleton. – Kirk Woll Aug 07 '10 at 00:31
  • @Kirk: Thanks for clear explanation, I now have better understanding of it. – Rachel Aug 07 '10 at 01:33
  • 9
    I do wish people would care more about patterns that aren't fast becoming anti-patterns. How often does anyone hear questions about the Observer pattern, or even MVC (which is all the rage these days)? No, they always have to ask about the one pattern that almost no one has good reason to use -- but they will use it anyway, cause it's easy and lets people pretend they're doing the right thing cause Hey, it's in the Book! BTW, that bit of nerd rage wasn't directed at you, Rachel...it was directed at your dumbass interviewer. – cHao Aug 07 '10 at 01:48
  • 2
    @cHao - +1...the singleton pattern should go away...but that's not saying singletons in general should go away (i.e., Spring Bean Factory stuff) – Tim Reddy Aug 07 '10 at 05:42

11 Answers11

15

There are a few ways to implement a Singleton pattern in Java:

// private constructor, public static instance
// usage: Blah.INSTANCE.someMethod();
public class Blah {
    public static final Blah INSTANCE = new Blah();
    private Blah() {
    }
    // public methods
}

// private constructor, public instance method
// usage: Woo.getInstance().someMethod();
public class Woo {
    private static final Woo INSTANCE = new Woo();
    private Woo() {
    }
    public static Woo getInstance() {
        return INSTANCE;
    }
    // public methods
}

// Java5+ single element enumeration (preferred approach)
// usage: Zing.INSTANCE.someMethod();
public enum Zing {
    INSTANCE;
    // public methods
}

Given the examples above, you will have a single instance per classloader.

Regarding using a singleton in a cluster...I'm not sure what the definition of "using" is...is the interviewer implying that a single instance is created across the cluster? I'm not sure if that makes a whole lot of sense...?

Lastly, defining a non-singleton object in spring is done simply via the attribute singleton="false".

Tim Reddy
  • 4,340
  • 1
  • 40
  • 77
  • For reference, the Singleton pattern includes a *protected* constructor. Something about being able to subclass/inherit/extend a singleton, as if that's not disaster-prone. – cHao Aug 07 '10 at 02:02
  • Shouldn't you `@Override` the Clone method? :-/ – st0le Aug 07 '10 at 05:05
  • 2
    With your second example, I would recommend putting the `INSTANCE` object inside of a private static inner class. The `getSingleton()` method then accesses the variable inside of the inner class, and the singleton does not exist until it's first needed (ie, lazy instantiation) – Brian S Aug 07 '10 at 05:18
  • @st0le: In Java, `clone()` is implemented in `Object`, but it throws a `CloneNotSupportedException` unless your class implements the `Cloneable` interface. If you don't implement the interface, it's impossible to clone the singleton. – Brian S Aug 07 '10 at 05:20
  • @Brian S: `public class Oopsie extends SingletonClass implements Cloneable`. – cHao Aug 07 '10 at 05:39
  • @Brian S - Interesting idea to use a private static inner class...all the more reason not to use the Singleton Pattern... :) – Tim Reddy Aug 07 '10 at 05:43
  • @T Reddy: Why would the inner class version be a reason to avoid the Singleton pattern? It just exploits the way Java loads classes for lazy instantiation of the Singleton. – Brian S Aug 08 '10 at 03:54
  • @cHao: With that example, you'd have to override `getInstance()` _and_ not override `clone()` in order for it to become a problem. Otherwise, `getInstance()` will return the static `SingletonClass` instance, not any `Oopsie` instance. And if it's not an `Oopsie` instance, then it doesn't implement `Cloneable`. – Brian S Aug 08 '10 at 04:01
  • @Brian S: Or, they could just add a constructor. Like lots of people do when they create a class. Once you can create a `new Oopsie()` at will, there's no need to implement `getInstance()`. – cHao Aug 08 '10 at 05:17
  • @cHao: I see what you're trying to say. It's also a bit silly to talk about overriding a static method (as I mentioned earlier) -- you can't override a static method, only shadow it. At that point, you might as well make `SingletonClass` a `final` class, and prevent the possibility for `Oopsie` at all. (Of course, `Oopsie` could override the member methods, but the only way of getting a singleton `Oopsie` would be to alter the code of the superclass, so why not alter the methods there?) – Brian S Aug 08 '10 at 11:14
  • @Brian S: You could have a singleton `Oopsie` if you wanted it, but without some work, even that ends up violating `SingletonClass`'s guarantee of one instance. You have to shadow getInstance() and the private static field, so you end up with two independent ways to create an instance -- and creating a `SingletonClass` and an `Oopsie` actually gives you two `SingletonClass`es. But if you make the class final, then you defeat one of the primary supposed benefits of Singleton over statics -- the ability to extend and swap out the singleton. It's all an ugly mess that's better to avoid. – cHao Aug 08 '10 at 11:51
  • 2
    @T Reddy: The inner class is not needless. For many uses, it may be overkill, but it performs its function of making the singleton have lazy instantiation. And Occam's Razor has absolutely nothing to do with the discussion at all. Occam's Razor is used to decide between multiple **theories**. We are discussing multiple **equally valid solutions**. – Brian S Aug 09 '10 at 02:25
  • Just to note, the spring singleton is a single instance per spring application context, not per class loader. – Luiggi Mendoza Sep 24 '13 at 17:29
  • ALL CAPS = eww. I say all caps should only be used for literal aliases (not everything that's `static final`). – Bernhard Barker Sep 24 '13 at 17:32
2

I disagree with @irreputable.

The scope of a Singleton is its node in the Classloader tree. Its containing classloader, and any child classloaders can see the Singleton.

It's important to understand this concept of scope, especially in the application servers which have intricate Classloader hierarchies.

For example, if you have a library in a jar file on the system classpath of an app server, and that library uses a Singleton, that Singleton is going to (likely) be the same for every "app" deployed in to the app server. That may or may not be a good thing (depends on the library).

Classloaders are, IMHO, one of the most important concepts in Java and the JVM, and Singletons play right in to that, so I think it is important for a Java programmer to "care".

Will Hartung
  • 115,893
  • 19
  • 128
  • 203
2

I find it hard to believe that so many answers missed the best standard practice for singletons - using Enums - this will give you a singleton whose scope is the class loader which is good enough for most purposes.

public enum Singleton { ONE_AND_ONLY_ONE ; ... members and other junk ... }

As for singletons at higher levels - perhaps I am being silly - but my inclination would be to distribute the JVM itself (and restrict the class loaders). Then the enum would be adequate to the job .

emory
  • 10,725
  • 2
  • 30
  • 58
  • 4
    Psh. The *best* standard practice for singletons is to avoid them if at all possible. And it's *always* possible at the application level. Their necessity is nowhere near as great as would be suggested by the billion people who learned about the Singleton pattern and were overjoyed at the ability to use a glorified global variable. – cHao Aug 07 '10 at 05:27
  • Conceded. singletons are nothing more than global variables. – emory Aug 07 '10 at 06:33
  • Globaltons indeed. I think the `enum` approach is just weird. We don't use an empty `enum` for classes of static methods. OTOH, using `enum` does highlight them as being freaky. – Tom Hawtin - tackline Aug 07 '10 at 12:03
1

Singleton is commonly implemented by having a static instance object (private SingletonType SingletonType.instance) that is lazily instantiated via a static SingletonType SingletonType.getInstance() method. There are many pitfalls to using singletons, so many, in fact, that many consider singleton to be a design anti-pattern. Given the questions about Spring, the interviewer probably was looking for an understanding not only of singletons but also their pitfalls as well as a workaround for these pitfalls known as dependency injection. You may find the video on the Google Guice page particularly helpful in understanding the pitfalls of singletons and how DI addresses this.

Michael Aaron Safyan
  • 93,612
  • 16
  • 138
  • 200
  • 1
    Can you provide an example showing what are the pitfalls and how DI addresses it, if this is out of scope here than can you provide some pointers to it ? – Rachel Aug 07 '10 at 01:38
1

3: Lastly he asked if it is possible to used Singleton Object with Clusters with explanation and is there any way to have Spring not implement Singleton Design Pattern when we make a call to Bean Factory to get the objects ?

The first part of this question is hard to answer without a technological context. If the cluster platform includes the ability to make calls on remote objects as if they were local objects (e.g. as is possible with EJBs using RMI or IIOP under the hood) then yes it can be done. For example, the JVM resident singleton objects could be proxies for a cluster-wide singleton object, that was initially located / wired via JNDI or something. But cluster-wide singletons are a potential bottleneck because each call on one of the singleton proxies results in an (expensive) RPC to a single remote object.

The second part of the question is that Spring Bean Factories can be configured with different scopes. The default is for singletons (scoped at the webapp level), but they can also be session or request scoped, or an application can define its own scoping mechanism.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • For Spring Bean Framework is it somehow possible to get multiple instances of an Bean rather than getting only one instance of Spring Bean which is by default for Spring ? – Rachel Aug 07 '10 at 01:28
  • @Rachel - that is what I said. The details are in the Spring documentation. – Stephen C Aug 07 '10 at 01:39
  • +1 for explaining the cluster mechanism for Singletons and EJB Approach. – Rachel Aug 07 '10 at 12:45
0

a static field can have multiple occurrences in one JVM - by using difference class loaders, the same class can be loaded and initialized multiple times, but each lives in isolation and JVM treat the result loaded classes as completely different classes.

I don't think a Java programmer should care, unless he's writing some frameworks. "One per VM" is a good enough answer. People often talk that way while strictly speaking they are saying "one per classloader".

Can we have one singleton per cluster? Well that's a game of concepts. I would not appreciate an interviewer word it that way.

irreputable
  • 44,725
  • 9
  • 65
  • 93
0
  1. There's the standard way, which you already covered. Also, most dependency-injection schemes have some way to mark a class as a singleton; this way, the class looks just like any other, but the framework makes sure that when you inject instances of that class, it's always the same instance.

  2. That's where it gets hairy. For example, if the class is initialized inside a Tomcat application context, then the singleton instance's lifetime is bound to that context. But it can be hard to predict where your classes will be initialized; so it's best not to make any assumptions. If you want to absolutely make sure that there's exactly one instance per context, you should bind it as an attribute of the ServletContext. (Or let a dependency-injection framework take care of it.)

  3. --

  4. Not sure I understand the question - but if you're talking about having a singleton instance that's shared between several cluster nodes, then I think EJB makes this possible (by way of remote beans), though I've never tried it. No idea how Spring does it.

Mike Baranczak
  • 8,291
  • 8
  • 47
  • 71
0

Singleton is a creational pattern and hence governs object instantiation. Creating singletons would mandate that you voluntarily or involuntarily give up control on creating the object and instead rely on some way of obtaining access to it.

This can be achieved using static methods or by dependency injection or using the factory pattern. The means is immaterial. In case of the normal protected constructor() approach, the consumer perforce needs to use the static method for accessing the singleton. In case of DI, the consumer voluntarily gives up control over the instantiation of the class and instead relies on a DI framework to inject the instance into itself.

As pointed out by other posters, the class loader in java would define the scope of the singleton. Singletons in clusters are usually "not single instances" but a collection of instances that exhibit similar behavior. These can be components in SOA.

raja kolluru
  • 602
  • 4
  • 5
0

The Following Code is from here

The Key point is you should Override the clone method...The Wikipedia example also is helpful.

public class SingletonObject
{
  private SingletonObject()
  {
    // no code req'd
  }

  public static SingletonObject getSingletonObject()
  {
    if (ref == null)
        // it's ok, we can call this constructor
        ref = new SingletonObject();        
    return ref;
  }

  public Object clone()
    throws CloneNotSupportedException
  {
    throw new CloneNotSupportedException(); 
    // that'll teach 'em
  }

  private static SingletonObject ref;
}
st0le
  • 33,375
  • 8
  • 89
  • 89
0

Query 1:

Different ways of creating Singleton

  1. Normal Singleton : static initialization
  2. ENUM
  3. Lazy Singleton : Double locking Singleton & : Initialization-on-demand_holder_idiom singleton

Have a look at below code:

public final class Singleton{
    private static final Singleton instance = new Singleton();

    public static Singleton getInstance(){
        return instance; 
    }
    public enum EnumSingleton {
        INSTANCE;   
    }   
    public static void main(String args[]){
        System.out.println("Singleton:"+Singleton.getInstance());
        System.out.println("Enum.."+EnumSingleton.INSTANCE);
        System.out.println("Lazy.."+LazySingleton.getInstance());
    }
}
final class LazySingleton {
    private LazySingleton() {}
    public static LazySingleton getInstance() {
        return LazyHolder.INSTANCE;
    }
    private static class LazyHolder {
        private static final LazySingleton INSTANCE = new LazySingleton();
    }
}

Related SE questions:

What is an efficient way to implement a singleton pattern in Java?

Query 2:

One Singleton instance is created per ClassLoader. If you want to avoid creation of Singleton object during Serializaiton, override below method and return same instance.

private Object readResolve()  { 
    return instance; 
}

Query 3:

To achieve a cluster level Singleton among multiple servers, store this Singleton object in a distributed caches like Terracotta, Coherence etc.

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

Singleton is a creational design pattern.

Intents of Singleton Design Pattern :

  • Ensure a class has only one instance, and provide a global point of access to it.
  • Encapsulated "just-in-time initialization" or "initialization on first use".

I'm showing three types of implementation here.

  1. Just in time initialization (Allocates memory during the first run, even if you don't use it)

    class Foo{
    
        // Initialized in first run
        private static Foo INSTANCE = new Foo();
    
        /**
        * Private constructor prevents instantiation from outside
        */
        private Foo() {}
    
        public static Foo getInstance(){
            return INSTANCE;
        }
    
    }
    
  2. Initialization on first use (or Lazy initialization)

    class Bar{
    
        private static Bar instance;
    
        /**
        * Private constructor prevents instantiation from outside
        */
        private Bar() {}
    
        public static Bar getInstance(){
    
            if (instance == null){
                // initialized in first call of getInstance()
                instance = new Bar();
            }
    
            return instance;
        }
    }
    
  3. This is another style of Lazy initialization but the advantage is, this solution is thread-safe without requiring special language constructs (i.e. volatile or synchronized). Read More at SourceMaking.com

    class Blaa{
    
        /**
         * Private constructor prevents instantiation from outside
         */
        private Blaa() {}
    
        /**
         * BlaaHolder is loaded on the first execution of Blaa.getInstance()
         * or the first access to SingletonHolder.INSTANCE, not before.
         */
        private static class BlaaHolder{
            public static Blaa INSTANCE = new Blaa();
        }
    
        public static Blaa getInstance(){
            return BlaaHolder.INSTANCE;
        }
    
    }
    
Partharaj Deb
  • 864
  • 1
  • 8
  • 22