JAVA Singleton Design Pattern

JAVA Singleton Design Pattern

Introduction

Ensuring that only one class instance exists can be crucial in software development. The Singleton Pattern is a widely used design pattern in Java that restricts the instantiation of a class to a single object while providing a global access point to it.

From database connections to logging frameworks, the Singleton pattern plays a vital role in ensuring controlled access to shared resources. In this article, we’ll explore the concept, implementation, and best practices of the Singleton pattern in Java.

Let's understand with an example:

Suppose we have one Browser class which we want to implement with the Singleton pattern. We need to follow the below 3 points -

  1. Create private static instance of the Browser class.
  2. Create a private constructor of the Browser class to prevent or avoid instantiation of the Browser class, i.e, no one can create the object of the Browser class.
  3. Create a public static getInstance method(getter method) to provide access to the instance/object of the Browser class.


Browser.java

package SingletonPattern;
public class Browser {
	private static Browser browser;
	private Browser() {};
	public static Browser getInstance() {
		if (browser == null) {
			browser = new Browser();}
		return browser;
	}
	public void browserInfoMethod() {
		System.out.println("Browser Info");
}}        

Create another test class i.e. TestBrowser.java class


Now, when we try to create the object of the Browser class, it displays an error like the one above because we have made the constructor of the Browser class private. We can only access the static methods of the Browser class, such as the getInstance() method, and this method is made static, so we can call the method in the TestBrowser class with its class name Browser.getInstance().

getInstance() method says that if the value of the Browser instance is null, then create an object of the Browser class, and return the browser reference. Then we can access the public method of the Browser class as below


The objective of Singleton Pattern is to create an object or do instantiation only once.

Use of Singleton Pattern in Multi-Threading environment.

Suppose we have 3 threads T1, T2, and T3. T1 goes to getInstance method and initially there is no instantiation of Browser class so browser reference is null and it will go inside the if block and create the Browser class object. Now, second thread T2 will come and there is already an object created, and so browser ref is not null and it will return the copy of the first browser reference. And the same happens with the third thread, i.e., the same browser reference will be given to any number of threads accessing the Browser class.

But we have to do a proper thread management, i.e., to achieve thread safety so that simultaneously all threads are not accessing the Browser static method. We use synchronized keyword with static getInstance() as below. This will introduce proper locking, when T1 uses getInstance(), it will lock the method and once done it will release the lock only then T2 can use getInstance() method lock it and release it, in the same way each thread will access the getInstance() method with proper lock and release.


Now, again we can face Performance Overhead issue in multi-threading environment as all threads are running sequentially. So instead of using the synchronized keyword, we can optimize our code by implementing double check synchronization or double check instantiation.

Let's see how we can optimize our code.

  • Remove synchronized keyword from getInstance().
  • Add first check or outer check


  • We will add synchronized for our singleton class Browser and add an inner check. Here we are not adding synchronization at method level and not violating the singleton pattern.

All Threads T1, T2, and T3 can access the getInstance method simultaneously. T1 checks the outer check if block and creates the object, then T2 approach will not enter the outer check as browser ref is not null and will return the copy of browser ref created by T1. Any number of Thread approaches, but will work in the same way.


  • We can use a volatile keyword with browser reference to make sure that all threads are systematically getting the copy of the browser without any problem. It is good practice.


So in this way we are having a good code optimization and we are creating only a single object and achieving the Singleton Pattern for our Browser class.

Let's understand with an example, how multiple threads are accessing the single object of the singleton Browser class.


Added log '' ''to show that the first thread creates the reference and other threads just use the same browser reference copy.



要查看或添加评论,请登录

Karishma Yadav的更多文章

  • JAVA - String Vs StringBuilder Vs StringBuffer

    JAVA - String Vs StringBuilder Vs StringBuffer

    String It is a sequence of characters. String Class objects are immutable, meaning they cannot be changed once created.

  • Java - Marker Interface

    Java - Marker Interface

    Interface with no fields or methods i.e.

  • Selenium 4- Launch Chrome, Firefox and Edge Browser

    Selenium 4- Launch Chrome, Firefox and Edge Browser

    Pre-requisite to run the selenium test script IDE - Eclipse IDE for Java Developers (version- 4.26.

  • Fundamentals of Git and GitHub

    Fundamentals of Git and GitHub

    What is Git? It is a Version Control System that helps us to track code changes. Why Git? Free and Open Source Fast And…

  • Assertions in Taiko

    Assertions in Taiko

    Assertions is a mechanism used to compare the actual output with the expected output while testing the functionality…

    1 条评论
  • Javascript - Miscellaneous

    Javascript - Miscellaneous

    Difference between null and undefined null and undefined are two distinct types that represent different values. By…

    3 条评论
  • Functions in Javascript

    Functions in Javascript

    A JavaScript function is a block of code designed to perform a particular task. Function Definition - Before we use a…

  • Higher-order Functions in JS

    Higher-order Functions in JS

    Higher order functions are functions that take one or more functions as arguments, or returns a function as its result.…

  • Arrow Functions In Javascript

    Arrow Functions In Javascript

    Arrow functions were introduced in the ES6 version. They make the code more structured and readable.

  • Looping Statements

    Looping Statements

    Looping statement is fundamental control structures in programming. Looping statements are used to execute a block of…