Q: What are design patterns

Slowly: Design pattern is a solution for common scenarios in system service design, which can solve common problems encountered in the development of functional logic. Design pattern is not limited to the final implementation scheme, but in this conceptual pattern, to solve the code logic problems in system design.


Q: What is a singleton

The singleton pattern ensures that the same object instance is used whenever it is used. The advantage of using the singleton pattern is that you don’t have to create and destroy object instances frequently, which reduces resource consumption.


Q: Get on the code!

There are many implementations of the singleton pattern, but ultimately it can be divided into two categories: the lazy pattern and the hungry pattern.

  1. Hungry mode: and created directly when the program starts, regardless of whether the object instance is useful later. (Will increase the system overhead)
public class Demo {

    private Demo(a){}  // Only getInstance can be called
  
    private static Singleton instance = new Singleton();   // Created directly when the class is loaded
    public static Singleton getInstance(a) {
        returninstance; Get this object}}Copy the code
  1. Lazy mode: Lazy mode creates objects only when we need them (and call getInstance()), so they won’t be created automatically if they’re not used. The slacker model has multiple implementations:
    • Static inner class schema
    • Thread unsafe mode
    • Thread-safe mode 1
    • Thread-safe Mode 2 (double-lock check)
    • Thread-safe mode 3 (using CAS)
    • Enumeration mode
// Static inner class schema
public class Demo {

    private Demo(a){}  // Only getInstance can be called

    private static class SingletonInner{
        private static Singleton instance = new Singleton();
    }

    public static Singleton getInstance(a) {
        returnSingletonInner.instance; }}Copy the code
Thread-unsafe mode, in which multiple instances are created at the same time under high concurrency
public class Demo {
    private static Singleton instance;

    private Demo(a){}  // Only getInstance can be called

    public static Singleton getInstance(a) {
        if (instance == null)
            instance = new Singleton();
        returninstance; }}Copy the code
Thread-safe mode 1, in which the lock granularity is very high and needs to be optimized
public class Demo {
    private static Singleton instance;

    private Demo(a){}  // Only getInstance can be called

    public synchronized static Singleton getInstance(a) {
        if (instance == null)
            instance = new Singleton();
        returninstance; }}Copy the code
Thread-safe mode 2: reduces the granularity of locks and synchronized from methods into code segments, but requires dual judgment
// When a thread blocks, it creates the instance first
public class Demo {
    private static Singleton instance;

    private Demo(a){}  // Only getInstance can be called

    public static Singleton getInstance(a) {
        if (instance == null) {
            synchronized (Demo.class) {
                if (instance == null)
                    instance = newSingleton(); }}returninstance; }}Copy the code
Thread-safe pattern 3: Use atomic classes to keep thread-safe
public class Demo {
    private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();
    private static Singleton instance;
  
    private Demo(a) {}
  
    public static Singleton getInstance(a) {
        for (;;) {   / / the spin lock
            Singleton instance = INSTANCE.get();
            if (null == instance)
                INSTANCE.compareAndSet(null.new Singleton());
            else 
                returninstance; }}}Copy the code
Public enum Singleton {INSTANCE; public void doSomething() { System.out.println("doSomething"); }} / / for the original model, need the Singleton INSTANCE of the function call like this: Demo. The getInstance (). DoSomething () / / and enumeration mode called: Singleton. The INSTANCE. The doSomethingCopy the code


Q: Enumerations are so hard to understand, why bother to learn them?

The method of enumeration is highly recommended by Bloch, a famous Programmer in the United States. Its implementation code is concise, even in the face of complex serialization or reflection attacks, serialization mechanism is provided for free.