Design pattern (5) - Singleton

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();
    }
}
Published 295 original articles · won praise 37 · views 30000 +

Guess you like

Origin blog.csdn.net/tianshan2010/article/details/104706054