Singleton (the Singleton) mode to ensure that only one instance of a class, and provide a global access point.
There are some objects in fact, we only need one, say the thread pool, cache, dialog processing target preferences and registry, log object, the object acts as a peripheral drivers, and so on. Using the Singleton pattern ensures that they have only one instance is created, and provides a global access point, create objects only when needed, and global objects as easy, nor as global variable has been created objects in the beginning of the program.
Single-mode embodiment is not complicated, using private constructors + getterInstance static method to complete.
public class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
The following is an example of a single embodiment mode, the code to simulate the process of production of a boiler plant Chocolate chocolate, chocolate boiler requires only a single instance of the class.
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance;
private ChocolateBoiler() {
empty = true;
boiled = false;
}
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
System.out.println("Creating unique instance of Chocolate Boiler");
uniqueInstance = new ChocolateBoiler();
}
System.out.println("Returning instance of Chocolate Boiler");
return uniqueInstance;
}
public void fill() {
if (isEmpty()) {
empty = false;
boiled = false;
// fill the boiler with a milk/chocolate mixture
}
}
public void drain() {
if (!isEmpty() && isBoiled()) {
// drain the boiled milk and chocolate
empty = true;
}
}
public void boil() {
if (!isEmpty() && !isBoiled()) {
// bring the contents to a boil
boiled = true;
}
}
public boolean isEmpty() {
return empty;
}
public boolean isBoiled() {
return boiled;
}
}
public class ChocolateController {
public static void main(String args[]) {
ChocolateBoiler boiler = ChocolateBoiler.getInstance();
boiler.fill();
boiler.boil();
boiler.drain();
// will return the existing instance
ChocolateBoiler boiler2 = ChocolateBoiler.getInstance();
}
}
Singleton and multithreading
In a multithreaded environment, the method using the get taken where multiple instances will, contrary to the original intention of the singleton. solution:
- Disclaimer synchronized keyword: operating efficiency is low, the next thread wants to acquire objects, must wait on a thread releases the lock, before they can continue.
- Using the sync block: As with the first method for synchronous operation, inefficient
- A separate sync for certain important code: only the key code to instantiate an object of synchronization, there are still security thread
- Use DCL double check the lock mechanism: for instance objects together with the volatile keyword in the key block to add a class instance variables of the volatile keyword plus synchronized lock, can successfully solve the problem of multi-threaded "lazy mode" encounter .
- Built implemented using static class singleton pattern: DCL may be realized and the same effects.
Examples of the use of a DCL follows:
public class DCL {
private volatile static DCL uniqueInstance;
private DCL() {}
public static DCL getInstance() {
if (uniqueInstance == null) {
synchronized (DCL.class) {
if (uniqueInstance == null) {
uniqueInstance = new DCL();
}
}
}
return uniqueInstance;
}
}
public class DCLTest {
public static void main(String[] args) {
DCL dcl = DCL.getInstance();
}
}