Servus, my dear loyal fans! As the title states this blogpost will cover the Singleton Design Pattern and various implementations in Java. Let us get started…
Singleton pattern is one of the simplest design patterns in Java. It involves a single class which is responsible to create an object while making sure that only single object gets created. This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class. If we try to instantiate a second instance of the singleton class, the new variable will also point to the first instance that was created earlier. However, despite its simplicity from a class design perspective, there are quite a few bumps in its implementation that we are going to encounter. Stay tuned ;)
This way of instantiation ensures a class will only have one instance and also provides a global access to it. So, we are creating a Database and letting it manage a single instance of itself. Database uniqueDb is unique instance of our Database class(Singleton). Private constructor (Database)ensures only Database can instantiate this class. getInstance() method gives us ability to instantiate the class and return an instance of this class.
Despite db1 having another name passed to the constructor, running this class we will see the same outputs because db1 does not create a new Database instead it uses the db that was instantiated before.
This approach is called a double-checking locking. The main advantage of it is that it reduces the use of synchronization as it is expensive. So, as performance is a key aspect of Database work this approach of implementing Singleton pattern suits better as it drastically reduces the overhead compared to the previous examples. The volatile keyword in this case ensures multiple threads handle the Database instance correctly. In other words, prevents memory writes to be chaotic.
Another way to create a Database class and ensure it to be threadsafe, also known as EAGER creation. Synchronizing the method can decrease the performance so eager instantiation can be an option to prevent it. This option relies heavily on JVM as it guarantees the creation of the unique instance of the Database when the class is loaded. Creating instance of Database in a private static initializer ensures the code to be threadsafe. In this implementation our getInstance() method simply returns the static Database.
This way of Singleton creating is useful when dealing with multithreading. Additional synchronized keyword forces every incoming thread to wait for its turn before it can enter the getInstance() method Which means that two threads would not be able to enter this method at the same time.
In terms of practical use Singleton pattern is used in logging, caches, thread pools, configuration settings, device driver objects. It should be used when managing access to a resource which is shared by the entire application, and it would be destructive to potentially have multiple instances of the same class. Making sure that access to shared resources thread safe is one very good example of where this kind of pattern can be vital. Now that we have seen several types of Singleton pattern implementation and discovered the situations where each of them might be suitable and why, I would recommend you to try it out.
Book- Eric Freeman, Elisabeth Freeman, Kathy Sierra, Bert Bates-Head First Design Patterns -OReilly (2008)
Feel free to check my github repository where I posted several design patterns implemented in Java — https://github.com/Farida004/Software-Design-and-Patterns
Thank you for your precious time ;)