Introduction
Singleton pattern is probably the simplest design pattern that almost everyone knows. It helps create a single instance of the class. Often used to create classes for Database, Manager … Today, I read the code of the project I am doing, I discovered a great way to create Singleton, find out it is called Bill Pugh Singleton, after the name of the author. Come up with this. So I wrote this article to share with everyone an approach to Singleton.
Lazy Initialization
First, let’s take a look at the Singleton initialization that most people are using. Singleton pattern is implemented by creating an instance in a public method. This way has the disadvantage that when running in multiple threads, the instance can be initialized many times. At that time Singleton was no longer Singleton.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class LazyInitializedSingleton { private static LazyInitializedSingleton instance; private LazyInitializedSingleton() { } public static LazyInitializedSingleton getInstance() { if (instance == null) { instance = new LazyInitializedSingleton(); } return instance; } } |
Thread Safe Singleton
To overcome the disadvantages of Lazy Initialization, we added synchronized
to the public method. Then, only one instance is initiated by one thread at a time.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class ThreadSafeSingleton { private static ThreadSafeSingleton instance; private ThreadSafeSingleton() { } public static synchronized ThreadSafeSingleton getInstance() { if (instance == null) { instance = new ThreadSafeSingleton(); } return instance; } } |
However, the above method still has the disadvantage of reducing the performance of the app when calling because getInstance()
is a synchronized method
. So we have another way of adding the following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class ThreadSafeSingleton { private static ThreadSafeSingleton instance; private ThreadSafeSingleton() { } public static ThreadSafeSingleton getInstance() { if (instance == null) { synchronized (ThreadSafeSingleton.class) { if (instance == null) { instance = new ThreadSafeSingleton(); } } } return instance; } } |
As such, we only need to put effort into the first call getInstance()
.
Bill Pugh Singleton Implementation
Before Java 5, java memory had a lot of issues and the methods above failed when too many threads called the Singleton class’s getInstance()
method simultaneously. So Bill Pugh introduces a new Singleton implementation using the inner static helper class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class BillPughSingleton { private static class SingletonHelper { private static final BillPughSingleton INSTANCE = new BillPughSingleton(); } private BillPughSingleton() { } public static BillPughSingleton getInstance() { return SingletonHelper.INSTANCE; } } |
How do you see this? Too fast, too compact and still safe. When the Singleton class is loaded, the SingletonHelper class will still not be loaded into memory. Only when the getInstance()
method is called will the helper class load and create a singleton class instance. This method also does not require synchronization and check null repeatedly.
Epilogue
In the framework of the article, there are some more methods that I cannot list all, only bringing a new perspective on the Singleton pattern for everyone. Thank you everyone for reading!
Reference: https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples