...
Code Block |
---|
|
class MySingleton {
private static MySingleton _instance;
private MySingleton() {
// construct object . . .
// private constructor prevents instantiation by outside callers
}
// lazy initialization
// error, no synchronization on method access
public static MySingleton getInstance() {
if (_instance == null) {
_instance = new MySingleton();
}
return _instance;
}
// Remainder of class definition . . .
}
|
...
Code Block |
---|
|
// Also an error, synchronization does not prevent
// two calls of constructor.
public static MySingleton getInstance() {
if (_instance == null) {
synchronized (MySingleton.class) {
_instance = new MySingleton();
}
}
return _instance;
}
|
...
Code Block |
---|
|
class MySingleton {
private static MySingleton _instance;
private MySingleton() {
// construct object . . .
// private constructor prevents instantiation by outside callers
}
// lazy initialization
public static synchronized MySingleton getInstance() {
if (_instance == null) {
_instance = new MySingleton();
}
return _instance;
}
// Remainder of class definition . . .
}
|
...
Code Block |
---|
|
// double-checked locking
public static MySingleton getInstance() {
if (_instance == null) {
synchronized (MySingleton.class) {
if (_instance == null) {
_instance = new MySingleton();
}
}
}
}
|
...
Code Block |
---|
|
class MySingleton {
private static MySingleton _instance;
private MySingleton() {
// construct object . .
// private constructor prevents instantiation by outside callers
}
// lazy initialization
public static synchronized MySingleton getInstance() {
if (_instance == null) {
_instance = new MySingleton();
}
return _instance;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
// Remainder of class definition . . .
}
|
...
Code Block |
---|
|
public class ObjectPreserver implements Runnable {
private static ObjectPreserver lifeLine = new ObjectPreserver();
// Neither this class, nor HashSet will be garbage collected.
// References from HashSet to other objects will also exhibit this property
private static HashSet protectedSet = new HashSet();
private ObjectPreserver() {
new Thread(this).start(); // keeps the reference alive
}
public synchronized void run(){
try {
wait();
}
catch(InterruptedException e) { e.printStackTrace(); }
}
// Objects passed to this method will be preserved until
// the unpreserveObject method is called
public static void preserveObject(Object o) {
protectedSet.add(o);
}
// Unprotect the objects so that they can be garbage collected
public static void unpreserveObject(Object o) {
protectedSet.remove(o);
}
}
|
...
Using lazy initialization in a Singleton without synchronizing the getInstance()
method may lead to multiple instances and can thus violate the expected contract.
...