Java foundation Demo04 -- Java design pattern singleton pattern

Keywords: Java jvm Spring

java singleton mode means to ensure that there is only one instance of a class and provide the instance to the global during the whole system operation.

Main implementation mode:

1, Instant load

Class objects are created as soon as the class file is loaded, whether or not they are called. (starving Han style)
Advantages: fast access to objects, thread safety.
Disadvantages: class loading is slow, which consumes unnecessary resources of the system.

package package01_single;

public class Eager {
    //Static private member object all objects of this class share one (single example)
    private static Eager instance  = new Eager();
    //The private constructor cannot be created directly. The class cannot be inherited
    private Eager(){}
    //Get unique instance through static method
    public static Eager getInstance() {
        return instance;
    }
}
class EagerTest {
    public static void main(String[] args) {
        //Direct class name. Method name calls static method
        Eager eager01 = Eager.getInstance();
        Eager eager02 = Eager.getInstance();
        System.out.println(eager01);
        System.out.println(eager02);
    }
}

2, DCL double lock implementation

Only when the object needs to be called can the object be created (lazy type). By judging whether the object already exists to implement a single instance, a synchronous lock is added to ensure thread safety.
Advantages: both can ensure thread safety, and the single instance object initialization calls getInstance without synchronizing locks. The resource utilization rate is high.
Disadvantages: the first load is a little slow, and errors occasionally occur due to the JVM underlying model. Because the use class of private constructor cannot be inherited.

package package01_single;

public class DoubleCheckLock {
    private static DoubleCheckLock instance = null;
    private DoubleCheckLock() {}

    /**
     * The first level of judgment is to avoid unnecessary synchronization
     * The second level of judgment is to create an instance in the case of null
     */
    public static DoubleCheckLock getInstance() {
        if(instance == null) {
            synchronized (DoubleCheckLock.class) {
                if(instance == null) {
                    instance = new DoubleCheckLock();
                }
            }
        }
        return instance;
    }
}
class DoubleCheckLockTest {
    public static void main(String[] args) {
        //Direct class name. Method name calls static method
        DoubleCheckLock d1 = DoubleCheckLock.getInstance();
        DoubleCheckLock d2 = DoubleCheckLock.getInstance();
        System.out.println(d1);
        System.out.println(d2);
    }
}

3, Static inner class implementation

It is also a delayed load. java virtual machine ensures its thread safety without lock.
Advantages: thread safety, creating objects when using, reducing resource consumption.
Disadvantage: it needs two classes to implement. Although the internal class object is not created, its class object is still created. At the same time, the class cannot be inherited.

package package01_single;

public class StaticClass {
    private StaticClass() {}
    //Static inner class
    private static class StaticIndoor {
        private final static StaticClass instance = new StaticClass();
    }
    public static StaticClass getInstance() {
        return StaticIndoor.instance;
    }
}
class StaticClassTest {
    public static void main(String[] args) {
        StaticClass s1 = StaticClass.getInstance();
        StaticClass s2 = StaticClass.getInstance();
        System.out.println(s1);
        System.out.println(s2);
    }
}

4, Container implementation

Multiple singleton types are injected into a unified management container, and the singleton is guaranteed by a unique key value. This method solves the problem that classes cannot be inherited in static inner class implementation and DCL implementation. Spring-IOC uses container implementation.

package package01_single;

import java.util.HashMap;
import java.util.Map;

public class Container {
    private static Map<String,Object> map = new HashMap<String, Object>();
    private Container() {}
    public static void addInstance(String key, Object instance) {
        if(!map.containsKey(key)) {
            map.put(key,instance);
        }
    }
    public static Object getInstance(String key) {
        return map.get(key);
    }
}

class T implements Runnable {
    public void run() {
        Container.addInstance("object", new Object());
        Object instance = Container.getInstance("object");
        System.out.println(Thread.currentThread().getName() + " " + instance);
    }
}
class Test {
    public static void main(String[] args) {
        Thread t1 = new Thread(new T());
        Thread t2 = new Thread(new T());
        t1.start();
        t2.start();
    }
}

Posted by calande on Wed, 17 Jun 2020 21:43:25 -0700