Skip to content

Singleton Pattern Guide

Exactly one instance, reachable from everywhere

Builds on static and final

Stage 3core2 min read

The Singleton Pattern is a creational design pattern (a pattern about how objects get created). It makes sure a class has only one instance, and it gives every caller the same way to reach that instance.

1. Concept & Analogy

Imagine a Judge Analytics service that counts total "runs" and "submits" for the whole system. If every module writes its own new JudgeAnalytics(), each one gets separate counters, so no single "total" exists. A Singleton works like one shared whiteboard. Everyone reads and updates the same object, so the numbers always match.


2. Class Diagram

Loading diagram…

3. When to Use

  • Single resource: Use it when exactly one instance of a class must exist (e.g. configuration, connection pool, logger, or global analytics).
  • Global access: Use it when many places need that one instance, and you do not want to pass it through every constructor.
  • Shared state: Use it when the object holds data that must be the same everywhere in the application (e.g. total run/submit counts).

4. Key Benefits (SOLID and Consistency)

  • Single source of truth: One object holds the state, so there are no duplicate or conflicting copies.
  • Controlled creation: The constructor is private, so outside code cannot call new. Only getInstance() hands out the object.
  • Lazy initialization (optional): "Lazy" means built only when first needed. With the static-holder idiom (a small nested class that holds the instance), the object is created the first time someone asks for it.
  • Thread safety: The JVM loads the holder class only once, so creating the instance needs no explicit synchronization. The counters still need care, which is why the code uses AtomicInteger (two threads cannot lose an increment).

5. Pros and Cons

ProsCons
Single instance: Guarantees one object for the whole application.Global state: Tests and dependencies become harder to follow.
Global access: Easy to obtain the instance from anywhere.Hidden coupling: Many classes may depend on the singleton without saying so.
Lazy + thread-safe: The static holder gives both, with no extra locking.Lifecycle: The singleton lives as long as the program runs, so it is a poor fit for short-lived resources.

6. Real-World Applications

  • Logging: A single logger instance shared across the application.
  • Configuration: One config object loaded once and reused.
  • Database connection pools: One pool manager instance.
  • Caches: A single in-memory cache for the process.
  • Analytics/metrics: One object aggregating counts (e.g. runs, submits) system-wide.

In this topic

Done with this topic?

How well do you know it?