In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "how to use the singleton pattern of the design pattern series". In the daily operation, I believe that many people have doubts about how to use the singleton pattern of the design pattern series. The editor consulted all kinds of data and sorted out the simple and easy-to-use operation methods. I hope it will be helpful to answer the doubts about "how to use the singleton pattern of the design pattern series". Next, please follow the editor to study!
At the beginning, I would like to give you a question: why not use the static method instead of the singleton mode?
I will announce the answer to the question at the end. You can take a look at the question and see if you are thinking the same way as I am.
I'm sure you can often hear the students around you say that the single case is very simple, and you can do it yourself, but when it comes to yourself, can you speak thoroughly on a point of knowledge, and can divergent thinking lead to more answers? Or can you tell me the scenarios in which each of his modes is more suitable? This is worth pondering.
First, give a definition to the singleton: in the current process, there is one and only one instance of the class created through the singleton pattern.
A single case has the following characteristics:
In Java applications, the singleton pattern ensures that only one instance of the object exists in a JVM.
The constructor must be private and the external class cannot create the instance by calling the constructor method
Without an exposed set method, an external class cannot call the set method to create the instance
Provide a public get method to get a unique instance of this
So what are the benefits of the singleton model?
Some classes are created frequently, which is a lot of overhead for some large objects
Omit the new operator, reduce the use frequency of system memory, and reduce the pressure of GC
Some classes in the system, such as controller in spring, control the processing flow, and if the class can create multiple, the system is completely messed up.
Avoid repeated occupation of resources
All right, the definition of the singleton pattern is clear, and the benefits are understood. Let's take a look at a hungry Chinese style first.
Hungry Han style
Public class Singleton {/ / create an instance object private static Singleton instance = new Singleton (); / * Private constructor to prevent instantiation of * / private Singleton () {} / * static get method * / public static Singleton getInstance () {return instance;}}
The reason why it is called the hungry Han style can be understood as that he is hungry, and he wants to new the object in advance, so that the class exists directly even when others get the object for the first time, saving the expense of creating the class.
After I introduce the lazy guy, you will know the difference between the two and what scenarios they are applicable to.
Lazy style
Thread-unsafe mode
Public class Singleton {private static Singleton instance; private Singleton () {} public static Singleton getInstance () {if (instance = = null) {instance = new Singleton ();} return instance;}}
Lazy people can understand that he is lazy. When someone calls it for the first time, he finds that his instance is empty, then initializes it, and then assigns a value, and the later call is no different from the villain.
Comparison between slackers and villains: you can see that the difference between the two is basically the overhead of the first creation, as well as thread safety (slackers in thread-unsafe mode).
With this comparison, then their scenario is easy to understand. In many e-commerce scenarios, if this data is frequently accessed hot data, then I can use the villain mode to load in advance when the system starts (similar to cache preheating) so that even the first user call does not have creation overhead, and frequent calls do not waste memory.
As for the lazy type, we can use it in places that are not very hot. For example, if you are not sure that someone will call the data for a long time, then use the lazy guy. If you use the villain, but no one calls it after a few months, pre-loaded classes are wasted in memory.
Thread safety issues
I didn't lock the lazy guy on purpose. Everyone must be aware of the thread safety problem of lazy guy, right?
??? Forget? All right, warm man will remind you of it.
There may be a situation in which multiple threads call the getInstance method to get an instance of Singleton, so it is possible that when the first thread is executing if (instance==null), the instance is the incoming statement of null.
Before instance=new Singleton () is executed (when instance is null), the second thread also enters the if (instance==null) statement, because instance=new Singleton () has not been executed in the thread that entered the statement before, so it executes instance=new Singleton () to instantiate the Singleton object, because the second thread also enters the if statement, so it instantiates the Singleton object.
This leads to the instantiation of two Singleton objects, what to do?
Simple and rude, just add the lock, this is the code after the lock.
Public class Singleton {private static Singleton instance = null; / * private constructors to prevent instantiation of * / private Singleton () {} / * static get methods * / public static synchronized Singleton getInstance () {if (instance = = null) {instance = new Singleton ();} return instance;}}
This is a typical time-for-space writing method, regardless of three, seven or twenty-one, lock it up every time you create an instance, and then make a judgment, which seriously reduces the processing speed of the system.
Is there a better way to deal with it?
Yes, make a judgment twice through the double check lock. The code is as follows:
Public class Singleton {private static Singleton instance = null Private Singleton () {} public static Singleton getInstance () {/ / first check whether the instance exists. If not, enter the following synchronization block if (instance = = null) {/ / synchronization block. Thread-safe create instance synchronized (Singleton.class) {/ / check whether the instance exists again. Create the instance if (instance = = null) {instance = new Singleton () if it doesn't exist. } return instance;}}
The synchronized keyword is added internally, that is, it does not need to be locked when it is called, but only when the instance is null and the object is created, so the performance is improved to a certain extent.
But is there no problem?
Consider the following: the object creation and assignment operations in the Java instruction are done separately, that is, instance = new Singleton (); the statement is executed in two steps.
However, JVM does not guarantee the order of these two operations, which means that it is possible that JVM will allocate space to the new Singleton instance, then assign values directly to instance members, and then initialize the Singleton instance.
This may go wrong, let's take An and B threads as an example:
Thread An and thread B enter the first if judgment at the same time
A first enters the synchronized block. Since instance is null, it executes instance = new Singleton ()
Due to the optimization mechanism within JVM, JVM first draws some blank memory allocated to the Singleton instance and assigns values to the instance members (note that JVM does not start initializing the instance at this time), and then A leaves the synchronized block.
Image-20201212010622553
B enters the synchronized block, and since instance is not a null at this time, it immediately leaves the synchronized block and returns the result to the program that called the method.
At this point, the B thread intends to use the Singleton instance, only to find that it is not initialized, and an error occurs.
Add volatile to modify Singleton, and optimize it again:
Public class Singleton {private volatile static Singleton instance = null Private Singleton () {} public static Singleton getInstance () {/ / first check whether the instance exists. If not, enter the following synchronization block if (instance = = null) {/ / synchronization block. Thread-safe create instance synchronized (Singleton.class) {/ / check whether the instance exists again. Create the instance if (instance = = null) {instance = new Singleton () if it doesn't exist. } return instance;}}
* * variables modified by volatile will not be cached locally by the thread, and all thread reads and writes to the object will be synchronized to the main memory at the first time, thus ensuring the accuracy of the object among multiple threads * *
The role of volatile
Prevent instruction reordering because instance = new Singleton () is not an atomic operation
Make sure the memory is visible
This is a perfect way to write it, and it can safely create a unique instance without having much impact on performance.
But because the volatile keyword may block some of the necessary code optimizations in the virtual machine, it is not very efficient, is there a better way to write it?
Through static inner classes
Public class Singleton {/ * private constructor to prevent instantiation * / private Singleton () {} / * an inner class is used here to maintain singletons * / private static class SingletonFactory {private static Singleton instance = new Singleton ();} / * get instance * / public static Singleton getInstance () {return SingletonFactory.instance } / * if the object is used for serialization, the object can be guaranteed to be consistent before and after serialization * / public Object readResolve () {return getInstance ();}}
Using inner classes to maintain singleton implementations, JVM's internal mechanism ensures that when a class is loaded, the loading process of that class is thread mutually exclusive.
In this way, when we call getInstance for the first time, JVM can ensure that the instance is created only once and that the memory assigned to instance is initialized, so we don't have to worry about the above problems.
At the same time, this method only uses the mutex mechanism when it is called for the first time, which solves the problem of low performance. So let's summarize a perfect singleton model for the time being.
Is there a more perfect way to write it by enumerating:
Public enum Singleton {/ * defines an enumerated element, which represents an instance of Singleton. * / Instance;}
It is more concise to use enumerations to implement single instance control, and JVM provides a fundamental guarantee to absolutely prevent multiple instantiations, which is a more concise, efficient and secure way to implement singletons.
The last one is also my favorite (less code).
Summary
Finally, everyone should know how to write the singleton pattern, as well as the advantages and disadvantages and the use scenarios. Do you have an answer to the question at the beginning?
What? Forget the question? Question: why not use static methods instead of singleton patterns?
Both of them can actually achieve the ultimate goal of our loading, but one of them is object-based and the other is object-oriented, just as we can solve problems without object-oriented, object-oriented code provides a better programming idea.
If a method has nothing to do with the instance object of its class, it should be static, otherwise it should be non-static. If we really should use a non-static method, but when we do need to maintain only one instance when creating the class, we need to use the singleton pattern.
There are many types in our e-commerce system, there are many configurations and attributes, these configurations and attributes must exist, and they are public, and they need to exist throughout the life cycle, so only one copy is needed. At this time, if I need a new when I need it again, and then assign it to him, it is obviously a waste of memory and there is no point in assigning values.
So we use singleton pattern or static method to maintain one and only one of these values, but at this time these configurations and properties are obtained by object-oriented coding, we should use singleton pattern, or it is not object-oriented, but its own properties should be object-oriented, although we can also solve the problem by using static methods. But the best solution should also be to use singleton mode.
At this point, the study on "how to use the singleton pattern of the design pattern series" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.