GofPatterns GofPatterns


Singleton Pattern   «Prev  Next»
Lesson 13Perfect Singleton Design Pattern
ObjectiveWhat does it take to make the Singleton Design Pattern perfect

Perfect Singleton Design Pattern

Given :
11.class ChocolateBoiler { 
12. private static ChocolateBoiler boiler;
13. private ChocolateBoiler() { }
14. public static final ChocolateBoiler getInstance() {
15.  if(boiler == null) {
16.   boiler = new ChocolateBoiler();
17.  }
18.  return boiler;
19.}

The above code shows a class depicting the Singleton design pattern. What can be done to make it a perfect Singleton design pattern?
Please select 1 option:
  1. Remove the if statement on line 15
  2. The given code is already a perfect singleton design pattern.
  3. Mark the static boiler instance variable as final.
  4. Synchronize the getInstance method using synchronized keyword.


Answer : D
Explanation:
In this code fragment, there is a class ChocolateBoiler which has a
  1. static final method getInstance and
  2. a static instance variable boiler.
The default constructor of the ChocolateBoiler class is marked as private. The constructor of this class cannot be called from an outer class because it is private. This prevents the instantiation of the class from an outer class. Hence, only a static method inside the class can access the constructor of the class. The getInstance method serves this purpose and when the getInstance method is invoked, it checks for the boiler variable to be null. If yes, it instantiates the boiler variable, else it returns the object which is already referenced by the boiler variable.
Hence, it is verified that there is one and only one object that is created and returned when asked for. This type of design pattern is called the Singleton design pattern in Java. However, when multithreading comes into the picture, if two or more threads somehow enter the "if block" in the getInstance method, there will be two instances of the ChocolateBoiler which is contradictory to the Singleton pattern. So marking the getInstance method as synchronized ensures thread safety because only one thread will be able to enter the method at a time.


//According to the Oracle docs, the synchronized keyword should appear after the public keyword // https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
class PerfectChocolateBoiler {
 private static PerfectChocolateBoiler boiler;
 private PerfectChocolateBoiler() {	}
 public synchronized static final 
  PerfectChocolateBoiler getInstance() {
  if (boiler == null) {
   boiler = new PerfectChocolateBoiler();
  }
  return boiler;
 }
 public static void main(String[] args) {
  // more code here	 
 }
}