The Singleton's objective is to control object generation by limiting the number of objects to one. Due to the fact that there is only one Singleton instance, any Singleton instance fields, including static fields, will appear only once per class. Singletons are frequently used to control access to resources including such database connections or sockets. For example, if your database only permits one connection and if your JDBC driver is concerned with multithreading, the Single ensures that only one connection is made or only one thread utilises the connection at a time. In object-oriented programming, a singleton class is one that can only have one object (an example of a class) at a time. A singleton class in object-oriented programming is one that can only have one object (an example of the class) at a time. If we try to recreate the Singleton class after the first time, the variable will also correspond to the initial instance produced. So any changes we make to any variable within the class via any instance effect the variable of the single instance produced and are observable if we access that variable via any variable of that class type declared. Remember the following points when creating a class as a singleton class, or while designing a singleton class:
- Create a private function Object()
- Create a static method with the return type of this singleton class's object. This static method is written using the concept of lazy initialization.
Purpose of Singleton Class Function:
The fundamental role of a Singleton class is to limit the number of instances that can be produced to one. This frequently ensures resource access control, for example, for a socket or database connection. Memory space is not wasted while using the singleton class because it restricts instance creation. Because the object will be created only once rather than each time a new request is performed. We can utilise this one object as many times as needed. This is why, in multi-threaded and database applications, the Singleton paradigm in Java is commonly used for caching, logging, thread pooling, configuration settings, and other functions.
To design/create a singleton class and build a singleton class, we must first do the following:
1. Ensure that the class has only one instance.
2. Give that instance global access by.
- Declaring all of the class's constructors to be private.
- Including a static method that returns an instance reference.
- The static methods are written using the lazy initialization concept.
A private static variable is used to store the instance. Runtime classes, Action Servlets, and Service Locators are examples of singleton classes. The singleton class also includes private constructors and factory methods.
Difference Between Normal Class and the Singleton Class
A Singleton class is distinguished from other classes by the procedure of instantiating the class's object. A java function Object() is used to instantiate a standard class. To instantiate a singleton class, on the other hand, we use the getInstance() function. Another distinction is that a regular class is destroyed at the conclusion of an application's lifecycle, whereas a singleton class is not destroyed when an application is completed.
Singleton Class Pattern Variations
There are two types of singleton design patterns:
- Early Instantiation: The object is created at the time of load.
- Lazy Instantiation: The object is created based on the requirements.
Implementation: The distinction here is in terms of instantiation; for normal classes, using constructors, whereas for singleton classes, we use the getInstance() function. In general, we can use the class name as that of the function call when defining this process to avoid confusion. Because single instance is a static variable, it is set to some object rather than null. If we call the getInstance() method again because the single example is not null, it really is returned to the variables instead of instantiating new Singleton class again. The static method getInstance is used in the main class to instantiate a singleton object with three items x, y, and z. (). However, once object x is created, parameters y and z are assigned to it.
1. Method of Eager Initialization:
This is the simplest way to construct a Singleton class, as the instance is created at the time the class is loaded. To use this method to build a singleton class, perform the following steps:
- Declare the function Object() as a private one.
- The following step is to make a private class member for this Singleton class.
- You must now construct a factory method that will return the object of your class that we created as an instance of the class member.
- If you want to directly access this static instance, you can even declare a static member public.
You can see that whenever we instantiate an object, we use the getInstance() method rather than using the class function Object().However, it has its own drawbacks. If you use this method to create a class singleton, an instance will be created whether or not the application uses it. So, let's look at another technique to create a singleton class in Java.
2. Method of Lazy Initialization:
This approach is known as lazy initialization because it delays the construction of the class instance until it is used for the first time. It aids in preventing the production of unneeded class instances. To create a singleton class in this manner, perform the procedures outlined below:
- First and foremost, make the function Object()private.
- Then create a private static instance of this class, but do not instantiate it yet.
- Finally, write a factory method that checks to see if the instance member is null. If not, it will create and return an instance of the singleton class for you.
3. Singleton Thread Safe Method:
However, the preceding approach may present certain difficulties in concurrent circumstances. Multiple threads entering the if condition at the same time can cause problems because the singleton design is widely used with multi-threads. To circumvent this, we try to establish a thread-safe singleton class by synchronising the global access function. This assures that at any one time, only one thread is running this procedure. However, this strategy might be time-consuming because each time the method is summoned, it must wait for the lock to be released before it can be used. This slows down the process and leads us to the next option, Lazy Initialization with Double Lock.
4. Double Lock Method for Lazy Initialization:
We do not synchronise the methods in this way. Instead, we enclose the object creation function in a synchronised block. By checking the thread locks ahead of time, you can limit the number of lock acquisitions. This strategy usually leads in improved application performance.
5. Lazy Loading Method:
This technique is based on JSL (Java Language Specification), and the JVM will load static data members only when they are required. As a result, when the singleton class is loaded into the JVM, no instance of it is created. Furthermore, the global method is invoked in sequential order during programme execution. You don't have to manually synchronise the static getInstance() to load and initialise with this method. The static class member is invoked in the correct order, and the rest of the concurrent invocations of the global method are returned in the same order without the need for synchronisation overhead.
6. Method of Static Block Initialization:
In Java, this approach of constructing a singleton class is analogous to the eager initialization method. The only difference is that this class's instance is created within a static block with exception handling capability.
7. Method of Bill Pugh Implementation:
There were numerous difficulties with the memory model prior to Java 5. As a result, the approaches for constructing a Singleton class described above failed in specific cases in a multithreaded environment.As a result, the Bill Pugh Method was introduced, which employed the concept of inner static classes for a singleton. This method was discovered by Bill Pugh, hence it is known as the Bill Pugh Implementation Method.
We can use Eager initialization only if the cost of initialising a class is not unreasonably expensive in terms of resources, or if the object of a class is continually required by your software. If we wish to provide exception handling with the Eager Initialization approach, we can do so by using the Static block. We may also control instances using this way. When creating a Singleton class for a multithreaded environment, we can use the Double-check Locking mechanism. Make the method synchronised so that the application can work in a multithreading environment when implementing it.