Before you understand the singleton pattern, understand what a pattern is.
The so-called pattern refers to the specific fixed steps to solve a class of problems.
Singleton mode: a step that guarantees that a class has only one object in memory.
Types of Singleton patterns:
1, a hungry man single case mode.
2, lazy single case mode.
3, the registration of single-case mode. (Can ignore, want to know can self-check)
Understanding: First it uses less, in fact, the internal implementation is also used in the A Hungry man-type singleton, because of the static method block, its singleton is instantiated when the class is loaded.
Steps to a hungry man a singleton mode:
1. Privatization of the constructor function.
2. Declare a static reference type variable of this class and use that variable to point to this class of object.
3, provide a public static method to obtain the object of this class.
Note: A hungry man creates a static object at the same time as the class is created for use by the system and is not changed in the future, so it is inherently thread-safe. It is also a recommended single-case approach.
code example:
class singleton{ privatestaticnew Singleton (); Private Singleton () {} Public Static Singleton getinstance () { return s; }}
View Code
Lazy design mode steps:
1. Privatization of the constructor.
2. Declare a reference type variable for this class, but do not create an object,
3. Provide a public static method to obtain the object of this class, before obtaining the first to determine whether the class object has been created
, if it has already been created, then return the object directly, and if it has not yet been created, create the object of this class first.
And then back again.
code example:
class singleton2{ privatestatic Singleton2 s; Private Singleton2 () {} Public Static Singleton2 getinstance () { ifnull) { new Singleton2 (); } return s; }}
View Code
Note: The above-mentioned lazy single-case implementation does not take into account the thread safety problem, it is thread insecure, the concurrency environment is likely to have multiple singleton instances, to achieve thread safety, there are three ways, are the getinstance this method of transformation, to ensure that the lazy single-case thread safety.
1, on the GetInstance method plus synchronization
Public Static synchronized Singleton2 getinstance () { ifnull) { new Singleton2 (); } return s; }
View Code
2. Double check Lock
Public Static Singleton2 getinstance () { ifnull) { synchronized (Singleton2 . class { ifnull) { new Singleton2 ();} } } }
View Code
3. Static internal class
class singleton2{ private Singleton2 () {} public< /span> static class lazyholder{ private static final Singleton2 INSTANCE = New Singleton2 (); public static final Singleton2 getinstance () { return lazyholder.instance; } }
View Code
The difference between lazy design mode and a hungry man design mode:
A hungry man is the class once loaded, the singleton initialization is completed, to ensure that the getinstance, the singleton is already exist,
And lazy idle, only when the call getinstance, only to go back to initialize the singleton.
1. Thread Safety:
A hungry man is inherently thread-safe and can be used directly for multithreading without problems.
The lazy type itself is non-thread-safe, in order to achieve thread safety there are several ways to write, respectively, the above 1, 2, 3, these three implementations in the resource load and performance of some differences.
2. Resource Loading and performance:
A hungry man a static object is instantiated at the same time as the class is created, and will occupy a certain amount of memory regardless of whether the singleton will be used later, but correspondingly, the speed will be faster on the first call because its resources have been initialized,
And the lazy type as the name implies, will delay loading, in the first use of the singleton when the object will be instantiated, the first call to do the initialization, if you want to do more work, performance will be somewhat delayed, and then the same as the A Hungry man type.
There are some differences between the three implementations of 1, 2 and 3,
1th, in the method call added synchronization, although thread security, but each time to synchronize, will affect performance, after all, 99% of the case is not required to synchronize,
2nd, two null checks were made in getinstance to ensure that only the first invocation of the singleton will be synchronized, which is also thread-safe, while avoiding the performance loss of each synchronization
3rd, using the ClassLoader mechanism to ensure that there is only one thread when initializing instance, so it is thread-safe, and there is no performance loss, so I tend to use this one.
Extension: Thread safety
If your code is in a process where multiple threads are running at the same time, 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 is atomic to the thread, or the switch 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, which is thread-safe.
Single Case design mode