123ArticleOnline Logo
Welcome to 123ArticleOnline.com!
ALL >> Education >> View Article

Tutorial - How To Create Singleton Class In Java

Profile Picture
By Author: Ayushi
Total Articles: 1
Comment this article
Facebook ShareTwitter ShareGoogle+ ShareTwitter Share

Have you ever thought about how to correctly manage multiple instances of a class in a Java application? Maybe you've faced issues with excessive memory usage, or conflicting data across instances.

These are generic issues that developers face frequently, and they result in the creation of bugs that are quite difficult to eliminate.

Well, how do we go about solving this problem?

We introduce the Singleton class in this Java Tutorial.

The very problem is solved by the Singleton class in Java. It ensures that a given class instance is created only once throughout the application’s lifespan.

No matter if we’re talking about the database connection or a logging mechanism or any other resource, which ideally should be just one and the same throughout the whole application lifecycle, knowing how to create Singleton class in Java comes in handy.

Understanding the Importance of Singleton Class in Java Programming

Why should we care about the Singleton pattern?

Think about working on a large-scale Java application where multiple parts of the code need access to a shared resource—like ...
... a configuration file or a logging system. If we allow multiple instances of these classes, we end up with inconsistent data or, worse, race conditions in a multi-threaded environment.

By using a Singleton class, we centralise the management of these resources. This means:

Consistency: The resource is managed from a single point.

Efficiency: We reduce memory overhead by limiting the instance to just one.

Control: We have a clear handle on how and when the resource is accessed.

For instance, consider a scenario where we have a logging utility in our Java application. If we allow multiple instances of this utility, we might face issues where some logs aren't captured correctly, leading to gaps in our log files.

With the help of the Singleton class, all logging actions performed by the application are done through a single and coherent instance, thus eliminating these issues.

How to Create Singleton Class in Java: A Step-by-Step Guide

Developing a Singleton class in Java is not only about following a pattern; it is about ensuring the proper function of our application.

Private Constructor: Restricting Object Creation

The first thing to do to create Singleton class is ensuring that no one can create an instance of that class on their own.

The question then arises: How do we do that? By using a private constructor.

First, making the constructor private enables us to make sure that the creation of the Singleton instance can only be done through the getInstance() method. This helps in avoiding the formation of similar copies.

public class Singleton {
// Step 1: Create a private static instance of the class
private static Singleton instance;

// Step 2: Make the constructor private
private Singleton() {
// Initialization code
}

// Step 3: Provide a public static method to get the instance
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}


Static Method for Global Access: Ensuring a Single Instance

After that, a method that can provide access to the Singleton instance is required at any point. This is the area where such a concept as the static method serves its purpose.

The getInstance() method looks into its database if any instance of the class is already present. If it doesn’t, it initialises one; if it does, it just returns it.

This method makes sure that only one instance of the class will ever be created, no matter how many times getInstance() is called.

public class TestSingleton {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();

System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
}
}


Comparing Lazy Initialization vs. Eager Initialization Approaches

Now, let's talk about two ways to create a Singleton instance: Lazy Initialization and Eager Initialization.

Lazy Initialization

The instance is created only when it's needed, i.e., when getInstance() is called for the first time.

This saves memory but might introduce thread safety issues in multi-threaded environments.

Eager Initialization

When the class loads, the instance is created immediately.

This is safer in multi-threaded scenarios but might waste resources if the instance is never used.


Usually, Lazy Initialization is preferred when we're sure the instance might not always be needed.

Eager Initialization works well when we need the instance immediately and can afford the initial memory cost.

Here’s how Eager Initialization looks in code:

public class EagerSingleton {
// Step 1: Create an instance at the time of class loading
private static final EagerSingleton instance = new EagerSingleton();

// Step 2: Make the constructor private
private EagerSingleton() {
// Initialization code
}

// Step 3: Provide a public static method to get the instance
public static EagerSingleton getInstance() {
return instance;
}
}


Practical Code Examples of Singleton Class Implementations

Example 1: Lazy Initialization with Thread Safety Considerations
Lazy initialization is great when we want to save resources by creating the instance only when it's needed. But in a multi-threaded environment, things can get tricky.

Here’s a code example that not only uses lazy initialization but also ensures thread safety:

public class LazySingleton {
private static LazySingleton instance;

private LazySingleton() {
// Private constructor to prevent instantiation
}

public static synchronised LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}

public void displayMessage() {
System.out.println("Lazy Singleton Instance Created!");
}
}

public class SingletonTest {
public static void main(String[] args) {
LazySingleton singleton = LazySingleton.getInstance();
singleton.displayMessage();
}
}
Output:
Lazy Singleton Instance Created!


Here’s the key takeaway:
Synchronised block: Ensures that only one thread can access the getInstance() method at a time. In a multi-threaded system, this stops the creation of additional instances.

Example 2: Eager Initialization for Immediate Instance Creation
If you know that you’ll need the Singleton instance throughout your application's lifecycle, eager initialization might be the way to go. It creates the instance when the class is loaded.
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();

private EagerSingleton() {
// Private constructor to prevent instantiation
}

public static EagerSingleton getInstance() {
return instance;
}

public void showMessage() {
System.out.println("Eager Singleton Instance Created!");
}
}

public class SingletonTest {
public static void main(String[] args) {
EagerSingleton singleton = EagerSingleton.getInstance();
singleton.showMessage();
}
}


Output:
Eager Singleton Instance Created!


Here’s why this works:
Immediate creation: The instance is created at the time the class is compiled, and it is always available once the class is loaded.

Example 3: Implementing Double-Checked Locking in Singleton Class
Double-checked locking technique is a little more sophisticated than the classic locking technique attempting to make it perform better by reducing the overhead involved in acquiring a lock.

This is very useful especially in high performance operations.

public class DoubleCheckedLockingSingleton {
private static volatile DoubleCheckedLockingSingleton instance;

private DoubleCheckedLockingSingleton() {
// Private constructor to prevent instantiation
}

public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronised (DoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}

public void printMessage() {
System.out.println("Double-Checked Locking Singleton Instance Created!");
}
}

public class SingletonTest {
public static void main(String[] args) {
DoubleCheckedLockingSingleton singleton = DoubleCheckedLockingSingleton.getInstance();
singleton.printMessage();
}
}


Output:
Double-Checked Locking Singleton Instance Created!


What makes this special:

Volatile keyword: Ensures that multiple threads handle the instance variable correctly.

Double-checking: Reduces the performance cost of acquiring a lock by first checking if the instance is already initialised.

Real-World Use Cases and Advantages of Using Singleton Classes

Singleton classes aren’t just a coding exercise—they solve real problems in everyday applications.

Let’s look at some common scenarios where Singleton classes shine:

Database Connections: Managing database connections can be tricky. With a Singleton, we ensure that the same connection is reused, reducing overhead and maintaining consistency.

Logging: In large applications, multiple parts of the system need to log information. A Singleton logging utility ensures that all logs are written to the same file or console, making debugging easier.

Configuration Settings: Applications often rely on configuration files or environment settings. Using a Singleton to manage these ensures that all parts of the application read from the same configuration, preventing inconsistencies.

Advantages of Singleton classes:

Controlled access: By centralising the management of a resource, we avoid conflicts and ensure consistency.

Memory efficiency: Only one instance is created, saving memory, especially for heavy resources like database connections.

Ease of maintenance: Since there’s only one instance to manage, debugging and updating the resource is straightforward.

Key Differences Between Singleton Classes and Regular Java Classes
There is also a difference between Singleton classes and regular classes to be understood when choosing between these two to include in the project.

Here’s how they differ:
Instance Control:
Singleton: Only one instance is created and used throughout the application.

Regular Class: Multiple instances can be created as needed, leading to higher memory usage.

Memory Management:
Singleton: More memory-efficient as it restricts the number of instances.
Regular Class: This can lead to memory bloat if too many instances are created.

Global Access:
Singleton: Provides a global point of access to the instance, ensuring consistency.

Regular Class: Instances are independent, and there’s no guarantee of consistency across different parts of the application.

Thread Safety:
Singleton: Needs to be carefully implemented to be thread-safe, especially in lazy initialization.

Regular Class: Each instance operates independently, reducing the risk of conflicts in multi-threaded environments.

Guidelines on When to Use Singleton Classes and When to Avoid Them
When to Use Singleton Classes:

Centralised Resource Management: Use Singleton classes when a single resource, like a database connection, needs to be shared across the application.

Configuration Management: If your application has global settings or configurations that should be accessed uniformly, Singleton classes ensure consistency.

Logging: Centralising logging through a Singleton class ensures all logs are handled in a uniform way.

When to Avoid Singleton Classes:

Overhead of Global State: If your application can be modularised or instances can be independent, avoid Singletons. They can introduce tight coupling and a global state, which makes testing and maintenance harder.

Flexibility Issues: Singletons restrict the number of instances. In scenarios where different behaviours or states are required, consider using regular classes or other design patterns.

Difficulty in Unit Testing: Since Singleton classes are tightly coupled to their implementation, they can make unit testing more difficult. Mocking or replacing them in tests isn’t straightforward.

Total Views: 22Word Count: 2036See All articles From Author

Add Comment

Education Articles

1. This School In Dubai: A Pathway To Excellence And Global Citizenship
Author: mansurali2343

2. Mbbs In Russia: A Comprehensive Guide
Author: Mbbs Blog

3. Mbbs In Russia: A Comprehensive Guide Winter Intake
Author: Mbbs Blog

4. Mbbs In Romania: A Pathway To Successful Mbbs Career
Author: Mbbs Blog

5. Study In Europe Without Ielts | 9810264496 | Your Ultimate Guide By Study Metro Delhi
Author: Study Metro Delhi

6. Manual+selenium Testing Training Institute
Author: Himanshu

7. Achieve Career Success With Enrolled Agent Certification At Ilead Tax Academy
Author: Ileadtax Academy

8. Why China Is A Top Destination For Indian Students Pursuing Mbbs Abroad
Author: Mbbs Blog

9. Power Bi Training | Power Bi Training In Hyderabad
Author: Anika Sharma

10. Azure Data Engineer Course Online | Azure Data Engineer
Author: Eshwar

11. संघर्ष से प्रेरणा तक: संदीप भंसाली की डिजिटल क्रांति की कहानी
Author: Digital Azadi

12. Usa Visa Consultant In Warangal: Your Trusted Partner For Overseas Dreams
Author: Johnwick

13. Why Mbbs In Belarus Is The Perfect Choice For Indian Medical Aspirants
Author: Mbbs Blog

14. Photography And Mental Health
Author: Neeraja

15. Devops Course | Devops Training In Hyderabad
Author: visualpath

Login To Account
Login Email:
Password:
Forgot Password?
New User?
Sign Up Newsletter
Email Address: