Java design patterns - Singleton (Singleton Pattern)

definition

Singleton pattern is a relatively "simple" mode, which is defined as follows:

To ensure that a class has only one instance and provide a global access point to access it.

or

Ensure a class has only one instance, and provide a global point of access to it.

To ensure that only one instance of a particular class, and examples of their own and provide the instance of the whole system.

Please note that the "simple" double quotes the word, it is simple it is also simple, but in order to make good use of is not so simple, why do you say?

  • First, define the Singleton pattern is better understood, a clear scenario, the idea is relatively simple to achieve;
  • Secondly, many factors singleton in fact to be considered, such as lazy loading, thread-safe and circumstances, and so destroy the singleton. It is these factors lead singletons diverse implementations, and their advantages and disadvantages

Feature

  • Singleton class only one example;
  • Singleton class must create your own unique instance of its own;
  • Singleton class must provide this example to all other objects.

The basic steps

  1. Private static member variables: Create a unique instance of this class, use static member variables to save; To ensure safety, the privatization of the member variables
  2. Private constructor: Avoid other classes can create objects directly singleton class
  3. Public static methods: for other classes to get a unique instance of this class

Factors to consider

  • Lazy loading

  • Thread Safety

  • Destruction singleton

    • Serialization

      If Singleton class is serialized, only green plus implements Serializable statement is not sufficient. In order to maintain and ensure Singleton, you must declare all instance fields are transient (transient), and provides a method readResolve. Otherwise, every time you deserialize a serialized instance, will create a new object.

    • reflection

      Authorized clients can call the private constructor by reflection, it can be done by means of AccessibleObject.setAccessible method. If you need to guard against such attacks, modify the constructor so that it throws an exception when asked to create a second instance.

      private Singleton() { 
      		System.err.println("Singleton Constructor is invoked!");
      		if (singleton != null) {
      			System.err.println("实例已存在,无法初始化!");
      			throw new UnsupportedOperationException("实例已存在,无法初始化!");
      		}
      	}
      }
      复制代码
    • Object Copy

      In Java, the object can not be replicated by default, if realized Cloneable interface, and implements the clone method, you can create a new object directly through the object replication, the object is copied without calling the constructor of the class, so even private constructor, the object can still be copied. In general, the situation is like copying the need to consider very rarely that a singleton class will be offered to the case being copied, the best way to solve this problem is to singleton class do not implement the Cloneable interface.

    • Class loader

      If the singleton loaded by different class loader, it is possible that the presence of multiple instances of a single class of embodiments.

Method to realize

1, lazy style

Thread-safe (suitable for single-threaded)
public class Singleton {
    private static Singleton singleton;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}
复制代码
  • Advantages: delay loading
  • Disadvantages: thread-safe, it is possible to generate a plurality of multi-threaded environment instances

To solve the lazy man's "security thread" that can be getInstance () method is set to synchronize, so there will be a second implementation:

Thread Safety
public class Singleton {
    private static Singleton singleton;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}
复制代码
  • Advantages: lazy loading, and thread-safe
  • Disadvantages: inefficient, 99% of the cases actually does not require synchronization

2, hungry man style

public class Singleton {
    private static Singleton singleton = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return singleton;
    }
}
复制代码
  • Advantages: thread-safe, simple
  • Disadvantages: No lazy loading, class loading time to complete initialization, memory space may be wasted to some extent,

If it is not necessary to delay the loading of scenes, you can prioritize a hungry man style

3, double checking locks

public class Singleton {
    private static volatile Singleton singleton;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}
复制代码
  • Advantages: lazy loading, thread safety, and efficiency is also very good

  • Cons: to achieve a relatively complicated, JDK1.5 only support volatile later

  • Explanation

    • The synchronization method to synchronized block
    • A first blank determination is to address efficiency issues, you do not need to enter each time the synchronization code blocks
    • synchronized (Singleton.class) to solve thread safety issues
    • The second sentence to avoid multiple instances is empty
    • The volatile modifier prohibition instruction reordering

    Volatile say a few words here for many, many books and online double check the lock instances are not added volatile, in fact this is not true

    First, volatile of the two meanings:

    1. Visibility memory
    2. Prohibit instruction rearrangement

    Here we use mainly second semantics. So what is the instruction reorder it, refers to a means of compilers and processors to optimize program performance and to sort the sequence of instructions. Simple to understand, it is that the compiler of our code has been optimized, may be different in the actual execution of instructions in the order with our written procedures to ensure that only the results of the same source code, but do not guarantee the same order as the actual source code instructions .

    singleton = new Singleton();

    This code is actually divided into three steps when jvm execution:

    1. In open up a heap memory space;
    2. In the example of heap memory Singleton
    3. The objects (singleton) point to heap memory space

    Since the "instruction rearrangement" optimization, it is possible to perform the step 1-3-2, namely: the object is complete and no examples have been referenced but not empty, that is, in the second place the empty judgment is false, direct return singleton-- an unfinished instantiated object reference.

    Here it comes to Java memory model, memory barriers and other knowledge, this paper describes the singleton, so will not repeat them, interested students can own Baidu

4, static inner classes

public class Singleton {
    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}
复制代码

The difference between starving type is static inner classes SingletonHolder will only be loaded when the getInstance () method of the first call (to achieve a lazy loading effect).

Thus static inner class implementations can ensure thread safety, but also to ensure the uniqueness of a single embodiment, but also has a delay loading characteristics

5, enumerate

public enum  Singleton {
    INSTANCE;
    public void doSomething() {
        System.out.println("doSomething");
    }
}
复制代码

Advantages: enumerating all of the above advantages achieved with the embodiment, but also provides a free serialization mechanism to prevent multiple instantiation

Drawback: JDK1.5 only after the enum support; popularity is not high compared with the previous several ways

advantage

  • Since the singleton pattern in memory only one instance, reduces memory costs, in particular the need to create an object frequently, when destroyed, and create or destroy when they can not optimize the performance advantages Singleton pattern is very clear.
  • When due to a single embodiment only one example of pattern generation, is reduced system performance overhead when generating an object requires more resources, such as reading configuration, dependency produce other objects, may be produced by a direct application upon startup singleton object, then the permanent way to solve the memory-resident (Note that when using the garbage collection mechanism JVM singleton pattern in Java EE).
  • Singleton pattern to avoid multiple assignment of resources, such as file a written motion, since there is only one instance in memory, to avoid the same resource at the same time file write operations.
  • Singleton pattern may be provided in the system global access point, and to optimize access to shared resources, for example a singleton class design is responsible for handling all the data mapping table.

Shortcoming

  • Singleton interfaces generally do not expand very difficult to extend, in addition to modifying the code is substantially free of the second approach can be implemented. Why not add a single case of mode interfaces do? Because the interface of singletons is no sense, it requires "to instantiate", and provides a single instance, or abstract class is the interface can not be instantiated. Of course, in special cases, single-mode embodiment may be implemented interface inheritance is required in the system development environment is determined according to.
  • Singleton pattern of the test is negative. In a parallel development environment, if a single embodiment mode is not completed, is not available for testing, no interface can not use a virtual mock manner object.
  • Singleton and single responsibility principle conflict. A class should implement only a logical, not on whether it is a single example, is not to single cases depending on the environment, the singleton "To singleton" business logic and integrated in a class.

scenes to be used

In one system, requires only one object has a class and, if more than one object appears "adverse reaction" appears to be single-mode embodiment, the specific scene is as follows:

  • Request generation environment unique serial number;
  • Throughout the project, the need for a shared access point or shared data, such as a counter on a Web page, you can not put a time to refresh all records in the database, using the Singleton pattern to maintain the value of the counter, and make sure that is thread-safe;
  • Excessive create an object needs to consume resources, such as IO and access to databases and other resources;
  • Need to define a large number of static constant and static methods (e.g., tools) environment, embodiments may be single mode (of course, may be directly declared static mode).

Source Address: gitee.com/tianranll/j...

References: "Zen design pattern", "Effective Java"

Reproduced in: https: //juejin.im/post/5d011d4be51d45777621bb63

Guess you like

Origin blog.csdn.net/weixin_34292402/article/details/93181913