First, the concept
The singleton pattern in Java is a common design pattern, and the singleton pattern is divided into five types: The lazy one, the A hungry man one, the static inner class singleton, the enumeration single case and the double check lock single case.
The singleton mode has the following characteristics:
1, the Singleton class can have only one instance.
2, the Singleton class must create its own unique instance.
3. The Singleton class must provide this instance to all other objects.
Singleton mode ensures that a class has only one instance, and instantiates itself and provides this instance to the entire system. In a computer system, the driver objects of the Recycle Bin, Task Manager, thread pool, cache, log Object, dialog box, printer, video card are often designed as singleton. These apps have more or less the functionality of the resource manager. Each computer can have several printers, but only one printer Spooler to prevent both print jobs from being output to the printer at the same time. Each computer can have several communication ports, and the system should centrally manage these communication ports to prevent a communication port from being called simultaneously by two requests. In short, the singleton mode is chosen to avoid the inconsistent state and avoid contention for bulls.
Detailed explanations of two or five single-case patterns
1, lazy-type single case
Class lazysingleton{private static Lazysingleton singleton; Private Lazysingleton () {
} public static Lazysingleton getinstance () {if (singleton==null) {singleton=new Lazysingleton (); } return singleton; } }
Singleton by restricting the construction method to private to prevent the class from being instantiated externally, the unique instance of Singleton can only be accessed through the getinstance () method within the same virtual machine scope. (In fact , the Java reflection mechanism is the ability to instantiate a class constructed as private, which basically invalidates all Java Singleton implementations.) This issue is not discussed here, and it is deceiving to assume that the reflection mechanism does not exist. )
However, the above implementations do not take into account thread safety issues. Thread safety refers to the idea that if your code is in a process where multiple threads are running concurrently, these threads may run the code at the same time. If the result of each run is the same as the single-threaded run, and the value of the other variable is the same as expected, it is thread-safe. Or, the interface provided by a class or program for a thread is an atomic operation or a switchover between multiple threads does not result in ambiguity in the execution of the interface, that is, we do not have to consider the problem of synchronization. Obviously the above implementations do not meet the requirements of thread safety, and many singleton instances are likely to occur in concurrent environments.
We can make improvements to the lazy type as follows:
public class Singleton { private static Singleton instance=null; Private Singleton () { } public static synchronized Singleton getinstance () { if (instance==null) { Instance=new Singleton (); } return instance;} }
On the basis of lazy-type with a synchronous lock, so that in the case of multi-threaded can be used. For example, when two threads want to create an instance at the same time, because only one thread can get a synchronous lock at a time, when the first thread is locked, the second thread waits only. The first thread discovery instance was not created, created. The first thread releases the sync lock, and the second thread can add a synchronous lock, executing the following code. Because the first thread has already created the instance, the second thread does not need to create an instance. Ensure that there is only one instance in the multi-threaded environment.
Cons: Every time you get a singleton instance through the GetInstance method, there is a process to try to get a sync lock. And it is well known that locking is time-consuming. Can be avoided by avoiding it.
2, a Hungry Man type single case (recommended use)
Class hungrysingleton{private static Hungrysingleton singleton=new Hungrysingleton (); Private Hungrysingleton () {} public static Hungrysingleton getinstance () {return singleton; }}
Initial initialization of Static Singleton is created once. If we write a static method in the Singleton class that does not need to create an instance, it will still create an instance early. and reduce the memory usage.
Cons: No lazy loading effect, which reduces memory utilization.
3, static internal class single case
Class internalsingleton{private static Class singletonholder{private final static Internalsingleton instance= New Internalsingleton (); } private Internalsingleton () {} public static Internalsingleton getinstance () {return singletonholder.inst ance; }}
Defines a private inner class that, when used for the first time, creates an instance of the nested class. Whereas a class of type Singletonholder, called only in Singleton.getinstance (), cannot be used by others because of a private property, Singleholder is not called singleton.getinstance () The instance is not created.
Advantage: Static variable instance is not initialized when loading, because there is no active use to reach the lazy loading
4. Enumeration of single cases
Enum enumsingleton{INSTANCE; public void DoSomething () {}}
"Effective Java" authors recommend the method, the advantage: not only to avoid multi-threaded synchronization problems, but also to prevent deserialization re-create new objects
Five, double check lock single case, before and after two times to determine whether the instance exists
classlocksingleton{Private volatile StaticLocksingleton Singleton; PrivateLocksingleton () {}//See:http://www.ibm.com/developerworks/cn/java/j-dcl.html Public StaticLocksingleton getinstance () {if(singleton==NULL){ synchronized(Locksingleton.class){ if(singleton==NULL) {Singleton=NewLocksingleton (); } } } returnSingleton; } }
Only when Singleton is null, you need to obtain a synchronization lock and create the instance once. When an instance is created, there is no need to attempt to lock it.
Cons: Use double if to judge, complex, error prone.
Java single-instance mode detailed