Learn the Java singleton pattern example

  • 2020-04-01 02:45:21
  • OfStack

The singleton pattern has the following characteristics:
1. Singleton classes can only have one instance.
The singleton class must create its own unique instance.
3. The singleton class must provide this instance to all other objects.
The singleton pattern ensures that a class has only one instance and that it instantiates itself and provides that instance to the entire system. In computer systems, thread pools, caches, log objects, dialog boxes, printers, and graphics card driver objects are often designed as singletons. All of these applications are more or less a resource manager. Each computer can have several printers, but only one Printer Spooler, to avoid having two print jobs output to the Printer at the same time. Each computer can have a number of communication ports, which should be centrally managed so that one port is not simultaneously invoked by two requests. In short, the choice of singleton mode is to avoid inconsistent state, to avoid long.

Let's start with a classic singleton implementation.


public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton() {
   // Exists only to defeat instantiation.
}
public static Singleton getInstance() {   if (uniqueInstance == null) {
       uniqueInstance = new Singleton();
   }
   return uniqueInstance;
}
// Other methods...
}

Singleton avoids classes being instantiated externally by limiting the constructor to private, and the only instance of Singleton within the same virtual machine scope can only be accessed through the getInstance () method. (in fact, it is possible to instantiate classes with constructors private through the Java reflection mechanism, which essentially invalidates all Java singletons. This issue will not be discussed here, but we will assume that the reflex mechanism does not exist.

But the above implementation does not consider thread safety. Thread safety is the idea that if your code is in a process where multiple threads are running at the same time, those threads might run the code at the same time. If the result of each run is the same as that of a single thread, and the values of other variables are the same as expected, it is thread-safe. In other words, the interface provided by a class or program is an atomic operation for a thread, or switching between multiple threads will not result in the ambiguity of the execution result of the interface, which means that we do not have to worry about synchronization. Obviously, the above implementation does not meet the thread-safe requirements, and multiple Singleton instances are likely to occur in a concurrent environment.


//Class. When the class is initialized, it is instantiated by itself
public class Singleton1 {
//Private default constructor
private Singleton1() {}
//It has been instantiated by itself
private static final Singleton1 single = new Singleton1();
//Static factory method
public static Singleton1 getInstance() {
return single;
}
}
//Lazy singleton class. Instantiated on first call
public class Singleton2 {
//Private default constructor
private Singleton2() {}
//Notice, there's no final here
private static Singleton2 single=null;
//Static factory method
public synchronized static Singleton2 getInstance() {
if (single == null) {
single = new Singleton2();
}
return single;
}
}


Related articles: