-2

I want to create a singleton object and I found 3 ways, which one is better and why are others bad. The constructor is assumed to be private.

Method 1:

class ClassX{  
   private static ClassX objX = null;

      static{
          objX = new ClassX();
      }

   //get objX method
 }

Method 2:

 class ClassX{  
   private static ClassX objX = new ClassX();

   //get objX method
 }

Method 3:

 class ClassX{  
   private static ClassX objX = null;

   public ClassX getInstance(){
      if(objX == null)
          return new ClassX();
      else
          return objX;
   }
 }
Harke
  • 1,279
  • 4
  • 25
  • 30
  • Consider using an `enum`. Also, lazy vs eager considerations are application specific. – Sotirios Delimanolis Oct 17 '13 at 20:09
  • I only see method 3 as singleton pattern :/ – Yichz Oct 17 '13 at 20:12
  • 1
    Use dependency injection instead. – millimoose Oct 17 '13 at 20:12
  • @Kossel Then I suggest you might want to get your eyes checked out :) All three snippets are singletons, method 3 is the only *lazily initialised* one. That is, assuming there's a `private` constructor, otherwise none of them guarantee a singleton. (Depends on how you define that term: an object of which only one instance *is* ever created; or an object of which only one instance *can* ever be created.) – millimoose Oct 17 '13 at 20:13
  • @Kossel: Why are other two not singleton? They also produce only one instance in a life time. – Harke Oct 17 '13 at 20:14
  • Yup, the constructor is assumed to be private. I have mentioned that. – Harke Oct 17 '13 at 20:16
  • possible duplicate of [What is an efficient way to implement a singleton pattern in Java?](http://stackoverflow.com/questions/70689/what-is-an-efficient-way-to-implement-a-singleton-pattern-in-java) – Bohemian Oct 17 '13 at 20:18
  • @millimoose doesn't singleton mean "an object of which only one instance can ever be created"? – Harke Oct 17 '13 at 20:19
  • @Harke Not necessarily. I maintain that it can mean both, depending on if you use the term in a design (pattern) context, or in an implementation one. That is, if I use dependency injection, and in my bootstrap code only create one instance of a component, and inject only this instance into every object that needs it as a collaborator, I'd say that this component is still a singleton even though there's nothing preventing anyone from (erroneously) creating another instance of it. – millimoose Oct 17 '13 at 20:20
  • I always use method 3, but didn't know it's lazy initialised one... I just read wikipedia, and they give pretty good description of each style – Yichz Oct 17 '13 at 20:22
  • Anyway, isn't the simplest safe way to do this `public static final INSTANCE = new Foo();`? – millimoose Oct 17 '13 at 20:24
  • 3
    A lot of users/answerers here seem to have no utter idea what exactly the singleton design pattern tries to solve. If you are such one, carefully read this: https://en.wikipedia.org/wiki/Singleton_pattern. The "best way" to implement it is either the Pugh or the Enum solution. Depending on the concrete functional requirements which the OP didn't tell any word about, the *right* way to achieve *that* functional requirement is however more than often [just create one](http://butunclebob.com/ArticleS.UncleBob.SingletonVsJustCreateOne). – BalusC Oct 17 '13 at 20:27
  • @BalusC I wish I could upvote that comment more than once. – millimoose Oct 17 '13 at 20:37

5 Answers5

7

You can try to use an enum like this:-

public enum Foo
{
   INSTANCE;
}

Also check out the related answer:- What is an efficient way to implement a singleton pattern in Java?

Quoting few lines from the Enforce the Singleton Property with a Private Constructor or an enum Type which Stephen Denne has used in the above answer:-

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.

Community
  • 1
  • 1
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
1
class ClassX {
    private static volatile ClassX instance = null;

    private ClassX() { }

    public ClassX getInstance() {
        if (instance == null) {
            synchronized (ClassX.class) {
                if (instance == null) {
                    instance = new ClassX();
                }
            }
        }
        return instance;
    }
}
lummycoder
  • 588
  • 1
  • 7
  • 20
  • Do people still try to use DCL in Java? Or did they fix the memory model. – Kayaman Oct 17 '13 at 20:18
  • @Kayaman I believe they did. EDIT: Yup, in Java 5: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html – millimoose Oct 17 '13 at 20:21
  • 1
    DCL is recommended by Joshua Bloch's book, "Effective Java." – bstempi Oct 17 '13 at 20:21
  • Okay, seems I'm a bit outdated on the memory model these days. But it still applies only to lazy-loading singletons, although I think a lot of people erroneously think that a singleton should always be lazy loaded. – Kayaman Oct 18 '13 at 05:31
0

Method 3 is not thread-safe, meaning that if multiple callers come in at the same time, you can end up with more than one singleton. Method 1 and 2 will work and are essentially the same thing. You might want to consider this example, using double check locking:

Class ClassX{  
   private static ClassX objX = null;

   public static ClassX getInstance(){
      if(objX == null)
          synchronized(this) {
              if(objX == null)
              objX = new ClassX();
          }

      return objX;
   }
}

It may seem silly, but double-checked locking is thread safe and far cheaper than using a synchronized version of getInstance(), which makes absolutely sure that you will only ever have 1 ClassX instance. Also, this allows you to pass data into getInstance() should you choose to use it as a factory or service locator who's job it is to create or store singletons.

bstempi
  • 2,023
  • 1
  • 15
  • 27
0

create a static final private instance & access it using a static getter and the construtor is private ofcourse.

private static final ClassX classX = new ClassX();

public static ClassX getInstance(){
  return classX;
}

or use dependency injection.

csn
  • 376
  • 7
  • 18
0

You do not need lazy initialisation:

class Foo {
    public static final Foo INSTANCE = new Foo();
    private Foo();
}

This probably won't resist serialization or reflection, but it should be good enough w/r/t thread safety. (Of course, you could also just create only one instance as I've implied in my comments.)

millimoose
  • 39,073
  • 9
  • 82
  • 134