May there be enough clouds in your life to make a beautiful sunset
introduce
Singleton means that a class is allowed to have only one instance in the entire program, that is, only one instance in the JVM. Singleton can be used in many ways, such as a single CEO in a company, a single dad in a family (barring those exceptions, of course), Singleton pattern is mainly used to frequent use of creating and using some of the classes, because there is only one instance, so save the memory overhead, all threads share the same instance, imagine that if a class to use is frequent, without using the singleton pattern, a thread needs to create an instance, There will be a lot of redundant instances, a lot of memory consumption, GC is easy to occur in the JVM, such as database connection pool, some of the less commonly used objects, can use singleton mode to help improve the availability of the system.
The type of singleton pattern
Singleton patterns can be written in many ways, and can be roughly classified as thread-safe and thread-unsafe. Let’s take a look at the specific types and how to implement them.
1. Hunchman singleton pattern
The hungry type as the name suggests is very hungry, want to immediately, just like a hungry man for a long time, want to immediately get the nourishing of love, change to come in to the program, too, an object is initialized at program startup, create a singleton object, that is to say, program is started, he immediately instantiated, the JVM is a singleton, Behind will not create, it is thread-safe, because the back of the thread to access, instance already exists, use it directly, don’t have to instantiate, so its efficiency is very high, but always there, we’ve seen, system startup it to initialize the object, and then if the instance is not a lot of use, That would be a waste of memory, and if the system has a large number of singletons, it might not make sense to use hungry. Let’s implement hungry.
When we look at the result of execution, we start multiple threads, and no matter how we execute, we get the same instance, because the initialization is done when the program starts, and the JVM already has this instance, so we use this instance.
Two. Lazy singleton pattern
LanHanShi just as its name implies is very lazy, lazy in real life are to the front to try so hard, the fire in our rural old man to have such a word, shit to figure out how to dig out the pit, so metaphor should be appropriate, change to come in to the program, there are a lot of examples, such as front end the tree structure of lazy loading, not all of a sudden to traverse all child nodes, But click on the layer, and then load the junior, LanHanShi is using such thoughts and loading again, when I need to use this advantage is to save memory space, if you don’t often use an object, we don’t need to load it in the program initialization, but it would appear thread safety issues, specific see code.
As shown in figure, the object to an initial value is empty, if the thread access, judgment to the object is empty, is instantiated, when the second thread access, because the first thread has been instantiated, so returned directly, without instantiated again, so there will be a kind of circumstance, if two or more than two threads to access it at the same time, When multiple threads run to the null-free condition, while the first thread hasn’t finished creating the object, the second thread decides that the object is still empty, so it creates it, so it creates two objects, so it’s not thread safe, and let’s see what happens.
After several runs, we find that we have created two objects, so how can we avoid this situation? Of course, there are ways to implement thread-safe problems using locks, as follows.
We use a synchronized lock to synchronize methods, so that each thread has to wait for the current thread to complete its access to access, so there is a problem. It is clear that only one thread needs to create the object and then other threads can use it. I just need to make a judgment call to return the object, but I still have a bunch of threads blocking outside, just for a judgment call, which is not reasonable, ok, let’s move on.
Iii. Double check Lock (DCL)
Lazy locking can achieve thread safety, but it is very inefficient, so we use double lock verification, the code is as follows.
We can see from the above code, the use of the two if judgment, we read about, if the object has not yet been instantiated, also is null, the two threads access at the same time, the two threads at the same time into the first if statement, but here on the synchronized code block when the first thread into the synchronized code block, the second thread is blocked, When the first thread completes its instantiation, the second thread enters the synchronized code block and decides that instance is not empty, it directly jumps out of the judgment and returns the instance. The subsequent threads pass the first judgment and return the instance directly, so that the efficiency becomes very high and there is no thread safety problem.
Static inner class implementation
Above we used the double way do check the singleton pattern, on the thread safety and efficiency are very few, but we still use synchronization locks, so there is no more elegant, more efficient writing, the answer is yes yes, we can use some of the features of Java, here USES a static inner class, as we know, Java inner classes are executed before the outer class, so that we can instantiate the inner class, and then the outer class gets the instance, as follows.
Because the static inner class has already instantiated the object at initialization time, there are no thread-safety issues.
Use enumerations
This approach, advocated by Effective Java author Josh Bloch, not only avoids multithreaded synchronization issues, but also automatically supports serialization, prevents deserialization from recreating new objects, and absolutely prevents multiple instantiations. However, since the enum feature was added later in JDK1.5, this approach protects against reflection attacks (all of the above can use reflection to get the private constructor of a class, enabling multiple instances to be created), whereas enums do.