Singleton pattern of java design pattern

Posted by double on Sat, 29 Jun 2019 20:49:44 +0200

  • I believe many children's shoes that make java have heard of it. But let them write it out at once. Even those who have 2-3 years'working experience may not be able to write a usable singleton pattern. So let's learn the singleton pattern today.
  • There are usually two modes

  • Immediate Loading-Hunger Mode: Immediate Loading is when the object is instantiated

    public class MyObject(){
    private static MyObject = new MyObject();
    .........................
    }

    • The delayed load-lazy mode is when the get() method is called, the object is instantiated.

Singleton mode:

public class SimpleSingle {

    /*Holding Private Static Instances to Prevent Application 
     * -Delayed Load Lazy Mode is that the object is not created when the object is called. 
     * Immediate Loading - Hunger mode = new object()
     * 
     * */
    private static SimpleSingle instance = null;

    /* Private construction methods to prevent instantiation */
    private SimpleSingle() {
    }

    /**
     * There is no synchronization block. So the thread is insecure.
     * @return
     */
    public static SimpleSingle getIntance(){
        if(instance == null){
            instance = new SimpleSingle();
        }
        return instance;
    }
    /**If the object is used for serialization, the consistency of serialization can be maintained.**/
    public Object readResolve(){
        return instance;
    }


    /**
     * Thread-safe 
     * If synchronized is added to the method, it locks the object, which is inefficient because it only needs to be locked after the first creation.
     * 
     */
     public static synchronized SimpleSingle getInstance1(){
         if(instance == null){
             instance = new SimpleSingle();
         }
         return instance;
     }
    /**
     * Creating Singleton Objects Using Synchronized Code Blocks
     * @return
     */
    public static SimpleSingle getInstance3(){

        if(instance == null){
            synchronized (SimpleSingle.class) {
                if(instance == null){
                instance =  new SimpleSingle();
                }
            }
        }
        return instance;
    }

}

The getIntance3() method doesn't seem to be a problem.
The synchronized keyword is added internally, which means that it is not necessary to add when invoked.
Locks, only when instance is null and objects are created, need to be locked, performance has a certain improvement. But in this case,
It's still possible to have problems with creating objects in Java instructions and assigning operations separately, that is to say, in Java instructions.
instance = new Singleton(); the statement is executed in two steps. But the JVM does not guarantee the order of these two operations, that is
It's possible that the JVM will allocate space for the new Singleton instance, assign it directly to the instance member, and then initialize it.
A Singleton instance. This may lead to errors. Let's take threads A and B as examples.
Threads a > A and B enter the first if judgment at the same time
B > A first enters the synchronized block, because instance is null, it executes instance = new Singleton();
C > Because of the optimization mechanism within the JVM, the JVM first draws some blank memory allocated to the Singleton instance and assigns it to the instance.
Members (note that the JVM did not start initializing the instance at this point), and A left the synchronized block. D > B enters the synchronized block. Because instance is not null at this time, it immediately leaves the synchronized block and returns the result.
Returns to the program calling this method.
E > At this point, the B thread intends to use the Singleton instance, but finds that it has not been initialized, and the error occurs.

In fact, the singleton pattern uses internal classes to maintain the implementation of singletons, and the internal mechanism of JVM ensures that when a class is loaded.
Wait, the loading process of this class is threaded mutually exclusive. So when we call getInstance for the first time, the JVM can protect us.
Certificate instance is created only once, and the memory assigned to instance is initialized, so we don't have to worry about it.
Face problems. At the same time, this method only uses the mutex mechanism in the first call, which solves the problem of low performance. So we
Summarize a perfect singleton model for the time being:

public class Singleton {

 /* Private construction methods to prevent instantiation */
 private Singleton() {
 }

 /* An internal class is used here to maintain the singleton */
 private static class SingletonFactory {
 private static Singleton instance = new Singleton();
 }

 /* Get an instance */
 public static Singleton getInstance() {
 return SingletonFactory.instance;
 }

 /* If the object is used for serialization, it is guaranteed to be consistent before and after serialization. */
 public Object readResolve() {
 return getInstance();
 }
 }

There are a lot of singleton patterns in the world. But I still like the double-check-locking singleton pattern I wrote myself.
Double detection of dcl is used to realize the singleton mode.

/**
 * Given the problem with the previously written multithreaded singleton pattern.
 * This time I'm writing a dcl double check singleton pattern
 * ---doble chek locking
 */

public class MyObject {
    //Static instances prevent being Instanced
    private volatile static MyObject myObject;

    private MyObject() {
    }

    /**
     * Dual detection mechanism is used to solve the problem. It does not need the asynchronism of synchronous code.
     * You can also keep the singleton.
     * @return
     */
    public static  MyObject getInstance(){

        try {
            if (myObject != null) {

            }else{
//              Thread.sleep(3000);
                synchronized (MyObject.class) {
                    if(myObject == null){
                        myObject = new MyObject();
                    }

                }
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return myObject;
    }


}

Topics: jvm Java