I caishuxueqian, just use blog this platform to organize the ideas
Using singleton mode simply means that the properties are the same when the object is generated, that is, you are new 100 times, and the results are all the same (such as obtaining static resource files, tool classes, etc.). So there is no need to generate multiple objects wasted server memory, he and static class is different, because the singleton is also the object system, long-term not used, but also to the CG clear. However, static classes have different member variables and static methods that exist throughout the lifetime of the program, such as when the server is loaded after loading the server. Will always be there, the same as the ServletContext object of the servlet and the Application object of the JSP
The core of a singleton pattern is a class that generates only one object of this class.
The following is the most primitive lazy mode (lazy is not automatically initialize the singleton when the class loads, you need to build manually)
/** * Created by wyh on 3/4/2017. */public class Sington { private static Sington Sington; public static int identifycode; Insert a CAPTCHA to verify if more than one object was generated //private test test; Insert the object you want to combine private Sington () { //code: Initialize the object you are combining } public static Sington getinstance () { if (sington==null) { sington=new Sington (); identifycode++; } return Sington; } public void Method () { //code. }}
Unlike a generic constructed class object, he shields the constructor (the constructor implicitly specifies static, see thing in Java), provides only a static build object getinstance, and then controls the number of objects generated in this method.
What if there are two users who have access to this method at the same time? is that a single case?
Here you can make a test with a simple thread:
/** * Created by wyh on 3/4/2017. */public class MyThread extends Thread { @Override public void Run () { System.out.println ( Sington.getinstance ()); } public static void Main (string[] args) { int i = 0; while (sington.identifycode!=2) { //If the verification code becomes 2, it indicates that two objects were generated for (int j=0;j<2;j++)//Impersonate two users to access this method at the same time new MyThread (). Start (); i++; } System.out.println (i+ "), a second Sington object is generated;} }
After testing, there were about two occurrences of the second object, namely, the outer loop 6 times and 14 times, the rest of the time did not. 99% will not appear.
What is this phenomenon? I understand that two threads (two users), just at the same time access to this method, the CPU to perform data operations is single-threaded, but very fast, the nanosecond level of the high and low level from this register to the register or in memory so pass, There is a register that stores the memory or register address of the next time you want to pass the data (learn the assembly to understand it). Back to the point, two threads at the same time, this at the same time in fact there must be sequential, it said, the CPU is single-threaded, not multi-threading. The front entry thread did not complete the method, The next thread enters again, performs a portion of the data operation, and then goes back to the remaining threads, so the resulting two objects will appear.
So how to avoid it?
The first is to add synchronize directly to the method name, simply to lock the method, and if the previous thread is not finished, the other thread cannot access the method
synchronized static Singleton getinstance () { if (sington==null) { sington=new Singleton (); identifycode++; } return Sington; }
But said above, 99% cases will not encounter the appearance of a second object, so do not play the maximum performance of the cup, lossy efficiency, that is, single-threaded, can not play the advantages of multithreading
Lazy mode has a double-check notation.
public static Singleton getinstance () { if (singleton==null) { //first judgment is null synchronized ( Singleton.class) { ///In a code block with a synchronous lock if the current thread is already wired access to the blocking state if (singleton==null) {////When the second thread is accessed is not NULL then no more objects are created Singleton=new Singleton (); }}} return singleton; }
Here's a test:
/** * Created by wyh on 3/4/2017. */public class MyThread extends Thread {private int anint; Public MyThread (int i) {this.anint=i; } @Override public void Run () {singleton.getinstance (anint); public static void Main (string[] args) {for (int i = 0;i<3;i++) {new MyThread (i). Start (); }}}/** * Created by wyh on 3/4/2017. */public class Singleton {private static Singleton Singleton; public static int identifycode; Whether multiple objects were generated when a verification code was inserted//private test test; Insert the object you want to group private Singleton () {//code: Initialize the object you are combining} public static Singleton getinstance (int i) {S Ystem.out.println ("Enter Method" +i); if (singleton==null) {//First judgment is null System.out.println ("Status 1 Thread---" +i); Synchronized (Singleton.class) {/////In a code block with a synchronous lock if the current thread has been accessed by a wired thread to a blocking state if (singleton==null) {/////n when the second thread is accessed Ull then no longer create object System.out.println ("Status 2 thread---" +i); Singleton=new Singleton (); }}} return singleton; } public void Method () {//code. }}
The result of the operation is:
I was simulating three threads to enter this method at the same time, you can see "Enter method 0 1 2" means that all three threads have entered the method
"Status 1 Thread 0 1" But two threads have entered the
if (singleton==null) {//code ...}
Why are there two of them? That's the equivalent of two users accessing this method at exactly the same time.
"Status 2 Thread 0" indicates that only one thread has entered the
Synchronized (singleton.class) { //code ... }
This is the reason for the sync lock, if there's two of them, it's odd, and it's weird.
This implements the Singleton object
Again, all threads enter the method, and only one thread enters the outer
if (singleton==null) {//code ...}
This indicates that the thread is running quickly, getting the CPU pro-gaze and letting him run at least to the location of the generated object
Singleton=new Singleton ();
When the other two threads enter, the forerunner has generated the object, and naturally cannot enter the object's null code block.
The result is the same.
The Main method is a main thread,
The code inside is a sub-thread, which can also be understood when your machine starts the main thread.
The CPU is also running threads for other applications .
public static Singleton getinstance (int i) { System.out.println ("Enter Method" +i); if (singleton==null) { //first judgment is null System.out.println ("Status 1 Thread---" +i); Synchronized (singleton.class) { ////In a code block with a synchronous lock if the current thread is already wired access to the blocking state if (singleton==null) {////When the second thread is accessed, it is no longer null Then the object System.out.println is no longer created ("Status 2 thread---" +i); Singleton=new Singleton ();}}}
the thread execution order is :
Thread 2 The first entry method executes the output statement and then changes to a blocking state
Thread 0 The second entry method executes the output statement and then changes to a blocking state
Thread 1 The second entry method executes the output statement and then changes to a blocking state
Then
Thread 1 first enters status 1 executes the output statement and then blocks again
Thread 2 The second enters status 1 executes the output and then becomes blocked again
Below
Thread 0 CPU Good He's got him first in the Sync Lock code block. Because the Synchronized keyword was added, he is in the current main thread
Must execute the code block and then turn to the other thread this peace-writing single-threaded Main method similarly
At last
Thread 1 finally entered status 1 other thread 0 2 has been entered.
But why does thread 1 still go to status 1?
if (singleton==null) //The first time to determine whether it is null System.out.println ("Status 1 Thread---" +i);
Did thread 0 not have an object already generated?
In fact, he had already entered status 1 earlier than the CPU to debug his output this sentence
A statement can be understood as a unit of a node run by a thread but I believe that the actual CPU is operating back and forth on different threads
The data to subdivide more, the CPU runs a billion of times per second Ah! The result you see is how many times the CPU is working back and forth data.
In summary its thread (small data run block) is the result of the CPU active scheduling and each CPU has his own set of scheduling rules
To support the windows hundreds of processes thousands of threads running tirelessly
You look at the foreground program and backstage program just he's too fast and you think it's running at the same time.
This and flash a reason multiple static pictures in the time can deceive the human eye extremely fast switch over 30 frames per second 60 frames
That's how you see the animation.
In multi-threading the same truth, just he this fast to hundreds of millions.
Because the CPU has only one CPU, he has only so many registers and a logical memory space to support his operations.
Unless you have multiple CPUs to achieve true sync operations
Back to Singleton mode, this double-check method
The efficiency will be higher than the whole method synchronized;
Add a lock to the key code to make it a single thread,
Other blocks are synchronized, and the lock efficiency is higher relative to the above
The above is a sample of two simple singleton patterns that I have introduced welcome advice
A brief talk on Java single-case model combined with multithreaded testing