Java instance parsing singleton pattern

  • 2021-12-05 06:25:58
  • OfStack

Introduction of directory singleton pattern advantages and disadvantages SynchronizedSynchronized example Synchronized versus non-SynchronizedSingleton 1 example 2 example 3 example 4 example 5 example

Introduction to Singleton Pattern

Singleton object (Singleton) is a common design pattern. In practice, the singleton object can guarantee that only one instance of the object exists in one JVM.

Advantages

1. Reduce system overhead and improve system performance
2. The new operator is omitted, which reduces the use frequency of system memory and relieves the pressure of GC
3. Avoid multiple occupation of shared resources

Disadvantages

1. Unsuitable for changeable objects
2. Difficulties in expansion
3. The responsibility of single case class is too heavy, which violates the principle of "single 1 responsibility" to a certain extent.

Synchronized

Example of Synchronized

Before introducing singleton mode, we will now introduce Synchronized under 1
Examples are as follows:
Create an inner class and open a child thread. If the class is instantiated, the test1 () method will be automatically executed


 class SynchronizedTest implements Runnable {
    private int count;

    public SynchronizedTest() {
        count = 0;
    }

    @Override
    public void run() {
        test1();
    }

    private void test1() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + count++);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

Construct an SynchronizedTest object and pass in two thread objects


 SynchronizedTest test = new SynchronizedTest();
        Thread thread1 = new Thread(test,"test1");
        Thread thread2 = new Thread(test,"test2");
        thread1.start();
        thread2.start();

It can be seen from the results that when one object holds the code block, the other thread cannot access the locked code block, and the other thread can execute only when the current one thread completes execution.

test1:0
test1:1
test1:2
test1:3
test1:4
test2:5
test2:6
test2:7
test2:8
test2:9

Synchronized and Non-Synchronized

Create an inner class


 class SynchronizedTest implements Runnable {
    private int count;

    public SynchronizedTest() {
        count = 0;
    }

    @Override
    public void run() {
        if (Thread.currentThread().getName().equals("S")) {
            test1();
        } else {
            test2();
        }
    }

    public void test1() {
        synchronized (this) {
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println(Thread.currentThread().getName() + ":" + (count++));
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void test2() {
        for (int i = 0; i < 5; i++) {
            try {
                System.out.println(Thread.currentThread().getName() + ":" + count);
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 }

SynchronizedTest test = new SynchronizedTest();
        Thread thread1 = new Thread(test,"S");
        Thread thread2 = new Thread(test,"N");
        thread1.start();
        thread2.start();

It can be seen from the results that one thread accesses Synchronized modified code blocks and the other thread accesses non-Synchronized code blocks without blocking

S:0
N:1
N:2
S:1
N:2
S:2
S:3
N:4
S:4
N:5

Singleton

Example 1

This example implements singleton, but if placed in multi-threaded, it will be full of loopholes
Let's move on to an improved example


public class Singleton {
/*  Hold a private static instance and prevent it from being referenced. Here, the value is null To achieve delayed loading  */
private static Singleton instance = null;
    /*  Private constructor to prevent instantiation  */
    private Singleton() {
    }
    /*  Static engineering method, creating instances  */
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

Example 2

According to the first example, we make improvements and add Synchronized.
But every time the getInstance () method is called, the object is locked. To reduce system overhead, we usually lock the object the first time we create it, and we don't need it later
Let's move on to an improved example


public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

Example 3

We improved on the previous example, only when instance = = null, that is, when the object is created for the first time, the locked area is executed. This approach solves the problem left over from the previous example, but in the Java directive, object creation and assignment operations are done separately, that is, instance = new Singleton (); Statement is executed in two steps. However, JVM does not guarantee the sequence of these two operations, which means that it is possible that JVM will allocate space for the new Singleton instance, then assign values directly to instance members, and then initialize this Singleton instance.


public static Singleton getInstance() {
if (instance == null) {
synchronized (instance) {
if (instance == null) {
instance = new Singleton();
      }
   }
 }
 return instance;
}

Example 4

At first glance, this code is no longer a problem. If an exception occurs in the constructor, the instance will not be created


public class Singleton {
/*  Private constructor to prevent instantiation  */
private Singleton() {
}
/*  Use here 1 Internal classes to maintain singletons  */
private static class SingletonFactory {
private static Singleton instance = new Singleton();
  }
/*  Get an instance  */
public static Singleton getInstance() {
return SingletonFactory.instance;
  }
}

Example 5


   private static Singleton instance = null;
   private Singleton(){

    }
    public static Singleton getInstance(){
        if (instance == null){
            sync();
        }
        return instance;
    }
   private static synchronized void sync(){
        if (instance == null){
           instance = new Singleton();
            System.out.println("success");
       }
    }

Related articles: