In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "what is the method of realizing the java singleton pattern". The content of the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what is the method of realizing the java singleton pattern".
As many people know, the creation of singletons can be roughly divided into two types:
Satiated Han type
Hungry Han type
The so-called hungry type is the object of a single case. I will create it first and take it directly when I come up. For example, this way:
Private static final Singleton singleton = new Singleton (); public static Singleton getInstance () {
Return singleton
}
There is nothing wrong with this implementation. What's the problem?
Sometimes, the object to implement Singleton is relatively large, or it is resource-consuming and time-consuming to create it, so we want to initialize it when needed, rather than when class is loaded, that is, to implement the so-called lazy load.
At this time, the question arises: how to write this so-called "satiated Chinese type"?
You may have seen this form of implementation.
Private static Singleton singleton
Public static Singleton getInstance () {
If (singleton = = null) {
Singleton = new Singleton ()
}
Return singleton
}
Is there a problem with such an implementation? Doesn't it feel great?
If you run in a single-threaded environment, you can also guarantee that only one instance is returned.
The problem is executing in a multithreaded environment.
When multiple threads execute, it is highly likely that two threads execute at the same time to determine whether it is null or not, and then create an instance at the same time. In order to solve the problem of multithreading, you did not hesitate to add synchronized to the method, which solved the problem without blood.
Here we go again!
When this method is used frequently, the mutex effect of synchronized results in only one thread at a time, which is very inefficient.
At this point, a clever idea comes to mind (of course, it may be from looking up information and browsing the Internet). Using double lock checking (Double lock checking) to improve efficiency looks like this:
Public static Single getInstance () {
If (singleton = = null) {
Synchronized (this) {
If (singleton = = null) {
Singleton = new Singletoon ()
}
}
}
Return singleton
}
Our method is not mutually exclusive and locks are checked only if the instance is empty. It looks unassailable!
There is a problem at this time, which is that the seemingly ordinary operation of new XXX is essentially the same as iTunes +.
This operation, like this, is not an atomic operation. For example, we have these lines of code:
Public class Test {
Private int i = 5
Private int a = 2
Public Test (int I, int a) {
This.i = I
This.a = a
}
Public void ttt () {
Test t = new Test (1); / / ordinary instantiation of an object
}
}
The steps that are roughly included are:
Create object
Initialize each field of the object and assign a value to it
Point an object to its reference
However, for the execution of these instructions, they are not necessarily executed in this order. For the sake of efficiency, these instructions are optimized and reordered. It is very likely that the object is created and points to its reference, but the fields are not initialized, and if used at this time, you get an object that is not fully constructed. (you can learn about object escape by referring to Java concurrent programming practice.)
In order to keep the code from being affected by optimization, Java 5, after revising the Java memory model (JMM), can use volatile declarations that do not allow instruction reordering.
The volatile keyword also ensures the order and visibility of memory and ensures that the program can be executed as expected. So, to implement a correct DCL singleton, you need to declare the singleton object as
Volatile, this must be important.
If we do not use DCL, we have other ways to achieve delayed initialization. For example, the following inner class form is also more commonly used.
Public class Foo {
Private static class FooHolder {
Static final Foo foo = new Foo ()
}
Public static Foo getFoo () {
Return FooHolder.foo
}
}
Because the inner class is initialized only when it is used, the delayed initialization of the singleton is guaranteed.
With all this in mind, let's take a look at how the singleton in Tomcat is used.
First, let's take a look at the use of DCL in Tomcat.
/ * * Whether the servlet needs reloading on next access * /
Private volatile boolean reload = true
Public Servlet getServlet () throws ServletException {
/ / DCL on 'reload' requires that' reload' be volatile
/ / (this also forces a read memory barrier, ensuring the
/ / new servlet object is read consistently)
If (reload) {
Synchronized (this) {
/ / Synchronizing on jsw enables simultaneous loading
/ / of different pages, but not the same page.
If (reload) {
/ / This is to maintain the original protocol.
Destroy ()
Final Servlet servlet
Servlet.init (config)
Reload = false
/ / Volatile 'reload' forces in order write of' theServlet' and new servlet object
}}}
Return theServlet
}
The above code is about the code when the Servlet corresponding to jsp is obtained, in which the use of DCL is mainly used to determine whether the class corresponding to the jsp file needs to be reloaded. (the working principle of jsp file has been introduced in the previous article. Interested friends can read the secret that JSP file modification takes effect in real time.)
For the use of a single case, the way in Tomcat is very simple
Public final class ApplicationFilterFactory {
Private static ApplicationFilterFactory factory = null
Private ApplicationFilterFactory () {
/ / Prevent instantiation outside of the getInstanceMethod ().
} / * *
* Return the factory instance.
, /
Public static ApplicationFilterFactory getInstance () {
If (factory = = null) {
Factory = new ApplicationFilterFactory ()
}
Return factory
}
We see that it is the same as the full Han type mentioned for the first time, without using DCL or adding it.
Synchronized, because for the use of ApplicationFactory here in Tomcat, initialization is triggered only when StandardWrapperValve is started, and it does not involve the use of a multithreaded environment, so you can rest assured to use this approach.
If you see the friends here, there is actually another way to implement the singleton, which is recommended by the author of Effective Java. It is easier to use. You only need an enum of the enumerated items, and then you can include the corresponding methods:
Public enum Singleton {
INSTANCE
Public void test () {
System.out.println ("test")
}
}
When we use it, we can just use it like this:
Singleton.INSTANCE.test (): thank you for your reading, the above is the content of "what is the method of realizing the java singleton pattern". After the study of this article, I believe you have a deeper understanding of what the method of realizing the java singleton pattern is, and the specific use still needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.