Java का Singleton Pattern
In this page:
class Singleton {
private static Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) instance = new Singleton();
return instance;
}
}
Eager Initialization
Eager initialization Singleton का एकमात्र instance उसी क्षण बना देता है जब class JVM द्वारा load होती है, चाहे यह आखिर में उपयोग हो या न हो। implement करने का यह सबसे सरल तरीका है, लेकिन इसकी कमी यह है कि यह उस run में भी instantiation की लागत हमेशा चुकाता है जहां singleton की असल में कभी ज़रूरत नहीं पड़ती।
उदाहरण: Eager Initialization
public class Main {
static class Singleton {
static final Singleton INSTANCE = new Singleton(); // created at class-load time, whether used or not
private Singleton() {}
}
public static void main(String[] args) {
System.out.println(Singleton.INSTANCE == Singleton.INSTANCE);
}
}
Login to try C/C++/Java/PHP code in the editor
Lazy Initialization
Lazy initialization इसके बजाय instance बनाने को तब तक टाल देता है जब तक यह पहली बार वाकई request नहीं होता, आगे का अनावश्यक काम टालते हुए। concurrent access के तहत lazy initialization को सुरक्षित बनाने के लिए, creation logic को एक synchronized method या block में wrap करना होगा ताकि दो threads दोनों अलग instances न बना सकें।
उदाहरण: Lazy Initialization
public class Main {
static class Singleton {
private static Singleton instance;
private Singleton() {}
static synchronized Singleton getInstance() {
if (instance == null) instance = new Singleton(); // created only when first requested
return instance;
}
}
public static void main(String[] args) {
System.out.println(Singleton.getInstance() == Singleton.getInstance());
}
}
Login to try C/C++/Java/PHP code in the editor
Double-Checked Locking
Double-checked locking हर access पर synchronize करने का overhead घटाता है यह दो बार जांच कर कि instance पहले से मौजूद है या नहीं: एक बार lock पाने से पहले, और फिर एक बार lock पाने के बाद, instance को सिर्फ तभी बनाते हुए जब यह अभी भी दोनों बार गायब हो। इस pattern के सुरक्षित होने के लिए instance field को volatile declare होना चाहिए, क्योंकि इसके बिना, दूसरे threads एक आधा-बना object देख सकते हैं।
उदाहरण: Double-Checked Locking
// Define the class Main
public class Main {
// Define the class Singleton
static class Singleton {
private static volatile Singleton instance;
private Singleton() {}
static Singleton getInstance() {
// Check whether instance == null
if (instance == null) {
// synchronized lets only one thread run this code at a time
synchronized (Singleton.class) {
if (instance == null) instance = new Singleton();
}
}
// Send instance back to the caller
return instance;
}
}
// Program entry point: the JVM starts running here
public static void main(String[] args) {
// Print a line to the console
System.out.println(Singleton.getInstance() == Singleton.getInstance());
}
}
Login to try C/C++/Java/PHP code in the editor
Enum Singleton
Enum singletons को JVM enums को handle करने के तरीके में बनी गारंटियों के कारण thread safety और serialization के ज़रिए duplicate instantiation से सुरक्षा लगभग मुफ़्त में मिल जाती है। कई अनुभवी Java developers इसे practice में Singleton implement करने का सबसे सरल और मज़बूत तरीका मानते हैं।
उदाहरण: Enum Singleton
public class Main {
enum Singleton {
INSTANCE;
void doWork() { System.out.println("Working"); }
}
public static void main(String[] args) {
Singleton.INSTANCE.doWork(); // thread-safe and serialization-safe for free
}
}
Login to try C/C++/Java/PHP code in the editor
Serialization & Reflection Protection
एक conventional (non-enum) Singleton गलती से deserialization के दौरान, या यहां तक कि reflection से किसी private constructor को दूसरी बार forcibly call करके भी duplicate हो सकता है। readResolve() method implement करना आपको deserialization को intercept करने और एक नए instance के बजाय मौजूदा singleton instance return करने देता है।
उदाहरण: Serialization & Reflection Protection
import java.io.*;
public class Main {
static class Singleton implements Serializable {
static final Singleton INSTANCE = new Singleton();
private Singleton() {}
protected Object readResolve() {
return INSTANCE; // returns the existing instance instead of a new one during deserialization
}
}
public static void main(String[] args) {
System.out.println(Singleton.INSTANCE);
}
}
Login to try C/C++/Java/PHP code in the editor
- multi-threaded code में
if (instance == null) instance = new Singleton();के साथ lazy initialization का उपयोग करना, जो दो instances बना सकता है। - field को
volatileचिह्नित किए बिना double-checked locking का उपयोग करना, जो किसी दूसरे thread को आधा-बना object देखने दे सकता है। - constructor को public छोड़ देना, ताकि कोई भी code
new Singleton()call कर सके और pattern टूट जाए।
Chapter Quiz — Complete all 14 topics to unlock
0/14 topics done
Complete these topics first:
- Java Design Patterns Introduction
- Java Singleton Pattern
- Java Factory Pattern
- Java Observer Pattern
- Java Builder Pattern
- Java MVC Architecture
- Java Adapter Pattern
- Java Decorator Pattern
- Java Strategy Pattern
- Java Command Pattern
- Java Facade Pattern
- Java Proxy Pattern
- Java Template Method Pattern
- Java Repository Pattern