Remember before

Yesterday, students complained about 23 design patterns in Java. She asked: Is there any way to break 23 design patterns, especially singleton patterns? I told her that Java 23 design patterns seem to be a lot, we should pick the key knowledge and combined with the program examples to memorize, especially after learning to write a design pattern by ourselves, it is easy to master. I showed her how to learn singleton patterns. Finally she laughed. “I see.”

Everyone who is new to Java’s 23 design patterns may feel that there are so many design patterns that they don’t want to learn them, especially when they are first introduced. So I wrote this article to explain the singleton pattern in the most straightforward language to help you understand.

The title of the article is just a gimmick. As learners of communication technology, we should keep our feet on the ground, so I will make sure that the content of the article is authentic!

Applicable scenario

An object needs to be created and destroyed frequently, and performance cannot be optimized when created or destroyed. For example, the recycle bin of Windows system is in singleton mode. One recycle bin is opened and another one is closed. The two recycle bins are the same.

The hungry type

Actively create a private static reference to the instance. The singleton already exists before the call.

Advantages: Simple and convenient, thread safe

Disadvantages: If the instance object is not called, memory resources are wasted

public class Singleton1 {
    // The thread is safe

    // Create a private static reference to your own instance
    private static Singleton1 singleton1 = new Singleton1();

    // Private constructor
    private Singleton1(a){}// Static factory method, a static public method that returns its own instance
    public static Singleton1 getSingleton1(a){
      returnsingleton1; }}Copy the code

LanHanShi

Creates instance objects when called. The singleton is initialized only when called.

Advantages: Simple and convenient, do not create objects when not using

Disadvantages: Thread is not safe. In the case of multiple threads, if one thread meets the judgment condition, another thread also enters the condition, multiple instance objects may be generated

public class Singleton2 {
  / / LanHanShi
  private static Singleton2 singleton2;
  private Singleton2(a){}public static Singleton2 getSingleton2(a){
    if(singleton2 == null){
      singleton2 = new Singleton2();
    }
    returnsingleton2; }}Copy the code

Monolock mode

Use the sychronized modified getSingleton () method

Advantages: Thread safety

Disadvantages: coarse granularity, large impact on the performance of the program

public class Singleton4 {
  private static Singleton4 singleton4 = null;

  private Singleton4(a){}public static synchronized Singleton4 getSingleton4(a) {
    if(singleton4 == null){
      singleton4 = new Singleton4();
    }
    returnsingleton4; }}Copy the code

Double locking judgment

Create a static lock and use two if judgments

Advantages: Thread safety, ensure the performance of the program, and save resources

public class Singleton3 {

  // Create a static read-only process-assist lock while the program is running
  private static Object syncRoot = new Object();

  private static Singleton3 singleton3;

  private Singleton3(a){}public static Singleton3 getSingleton3(a) {
    if(singleton3 == null) {// Check whether it exists
      synchronized (syncRoot){
        if(singleton3 == null){
          singleton3 = newSingleton3(); }}}returnsingleton3; }}Copy the code

Static inner class

Advantages: Not only achieves thread safety, but also avoids the performance impact caused by synchronization mechanism

public class Singleton6 {
  private static class LazyHolder{
    private static final Singleton6 singleton6 = 
        new Singleton6();
  }
  private Singleton6(a){}public static final Singleton6 getSingleton6(a){
    returnLazyHolder.singleton6; }}Copy the code

Registration type

Maintains a set of instances of singleton classes and puts them in a Map. For registered instances, they are returned from the Map directly. For unregistered instances, they are registered first and returned later.

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

public class Singleton5 {
  private static Map<String,Singleton5>
  map = new HashMap<>();
  static {
    Singleton5 singleton5 = new Singleton5();
    map.put(singleton5.getClass().getName(),
        singleton5);
  }
  private Singleton5(a){}public static Singleton5 getSingleton5( String name){
    if(name == null){
      name = Singleton5.class.getName();
    }
    if(map.get(name) == null) {try {
        map.put(name,(Singleton5) Class.forName(name).newInstance());
      } catch (InstantiationException e) {
        e.printStackTrace();
      } catch (IllegalAccessException e) {
        e.printStackTrace();
      } catch(ClassNotFoundException e) { e.printStackTrace(); }}returnmap.get(name); }}Copy the code

Advantages and disadvantages of the singleton pattern

advantages

  1. Save memory space by having only one object in memory

  2. Reduces the system performance overhead

  • For example, when an object requires many resources, such as reading configurations, generate other dependent objects. An instance object is generated directly when the application is started.
  1. Avoid multiple occupancy of resources
  • For example, write files, because there is only one instance, avoid writing to the same file at the same time.
  1. You can set up global access points on the system to optimize and share resource access.
  • For example, a singleton is designed to handle all data tables in the system.

disadvantages

  1. The singleton pattern generally has no interface and is difficult to extend unless you modify the code.

  2. Singleton objects that hold Context can easily leak memory.

conclusion

The singleton pattern is one of Java’s 23 design patterns. The singleton pattern is suitable for scenarios where objects need to be created and destroyed frequently and performance cannot be optimized.

This paper introduces hungriness, slacker and register in singleton pattern. Hungry and lazy need to focus on learning and understanding. Hunchstyle is naturally thread-safe, whereas lazy threads are not, leading to lazy single-lock mode, double-lock judgment, and static inner classes.