Matt W Matt W - 7 months ago 14
Java Question

Creating a Singleton Object in Java

In my Java program, I am attempting to ensure that only one object of the class "ATM" is created. For this, I have a classic singleton class as below:

public class Singleton {

private static Singleton uniqueInstance;

private Singleton() {}

public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}

}


How do I ensure that only one object of the class ATM is made? E.g. Where do I now put the code:

ATM theATM = new ATM();


Does this code belong in the singleton class, or within the ATM class?

Answer

You don't need that Singleton class, because your singleton has to be ATM.

So, just use this in ATM.java:

public class ATM {

    private static ATM uniqueInstance;

    private ATM() {}

    public static ATM getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new ATM();
        }
        return uniqueInstance;
    }

}

Now, you can call your line:

ATM theATM = new ATM();

only if you are in the ATM class itself, because your constructor is private, but this is useless because you care about uniqueInstance in this situation.

If you are in a different class, you should use:

public class Main {

    public static void main(String[] args) {
        ATM theATM = ATM.getInstance();
    }

}

The idea of the singleton pattern is that even if you run again ATM.getInstance();, the same (initial) instance (uniqueInstance) will be returned. If it wasn't initialized before, it is initialized. Otherwise, the old instance is returned. So, this is how you are sure that you won't have multiple instances.


Of course, there are better implementations of the singleton pattern that are thread safe.

E.g.:

  • thread safe - lazy:

    public class ATM {
        private static ATM uniqueInstance = null;
        private ATM(){}
        public static synchronized ATM getInstance() {
            if ( uniqueInstance == null ) {
                uniqueInstance = new ATM();
            }
            return uniqueInstance;
        }
    }
    
  • thread safe - eager

    public class ATM {
        private static ATM uniqueInstance = new ATM();
        private ATM(){}
        public static ATM getInstance() {
            return uniqueInstance;
        }
    }
    
  • thread safe - using enum

    public enum ATM {
        UNIQUE_INSTANCE;
        ...
    }