Preface: Recently read the "Java Multithreaded Programming core technology" a book, the sixth chapter of the Singleton mode and multithreading this chapter quite interested, I know I read the book or do not remember how much, write a blog record of what you learn is still very necessary, study expensive in insist.
Singleton mode, that is, a class has only one instance, any object to access the class can only be accessed through this instance object, we compare the house to a Java class, each house has only one key (like each class only one instance), so that only the owner of the house has the key to access the house, other people can not access.
Let's take a look at how to write a Java code for a singleton pattern in a number of ways:
1. Load now (also known as a Hungry man mode)
Let's take a look at the specific code.
package Singleton; public class Myclass { // private static Myclass myclass=new Myclass (); // The constructor is decorated with the private modifier private Myclass () {} public
static
Myclass getinstance () { return
MyClass; }}
Since the constructor is private, how do we invoke the object of this class? We can get this object by means of the class name + method, the code is as follows:
PackageSingleton; Public classTest1 { Public Static voidMain (string[] args) {//cannot generate a MyClass object with new, compile error//Myclass myclass=new mycalss ();Myclass myclass1=myclass.getinstance (); Myclass Myclass2=myclass.getinstance (); //Let's print out the hashcode of the above two objectsSystem.out.println (Myclass1.hashcode ()); System.out.println (Myclass2.hashcode ()); }}
2. Lazy loading (also known as lazy mode)
Let's look at the lazy pattern, which is to instantiate an object when the Get method is called.
PackageSingleton; Public classMyclass_1 {Private StaticMyclass_1 Myclass_1; Privatemyclass_1 () {} Public Staticmyclass_1 getinstance () {if(myclass_1!=NULL) { } Else{myclass_1=NewMyclass_1 (); } returnMyclass_1;} }
Test code
PackageSingleton; Public classTest1 { Public Static voidMain (string[] args) {//cannot generate a MyClass object with new, compile error//Myclass myclass=new mycalss (); /*Myclass myclass1=myclass.getinstance (); Myclass myclass2=myclass.getinstance ();*/myclass_1 MyClass1=myclass_1.getinstance (); Myclass_1 Myclass2=myclass_1.getinstance (); //Let's print out the hashcode of the above two objectsSystem.out.println (Myclass1.hashcode ()); System.out.println (Myclass2.hashcode ()); }}
The result of the operation is the same as the diagram above.
Actually, there is a big problem here. That's how lazy mode is completely wrong in multithreaded mode.
Let's see what it looks like under multiple threads.
The thread class code is as follows:
Package Singleton; Public class extends thread{ publicvoid run () { System.out.println (myclass_1. GetInstance (). Hashcode ());} }
Test code:
Package Singleton; Public class runtest {publicstaticvoid main (string[] args) { for ( int i = 0; I < 3; i++) { new Mythread (). Start (); }}}
Run results
You can see that two different instance objects were generated under multithreading. And what we want is a single case.
The following approach is to modify the getinstance directly with the Synchronized keyword, but this will lock the whole method, inefficient
PackageSingleton; Public classMyclass_1 {Private StaticMyclass_1 Myclass_1; Privatemyclass_1 () {} Public Static synchronizedmyclass_1 getinstance () {if(myclass_1!=NULL) { } Else{myclass_1=NewMyclass_1 (); } returnMyclass_1;} }
The following approach is done using a synchronous statement block, which is equally inefficient, and the above approach Dora
PackageSingleton; Public classMyclass_1 {Private StaticMyclass_1 Myclass_1; Privatemyclass_1 () {} Public Staticmyclass_1 getinstance () {synchronized(Myclass_1.class) { if(myclass_1!=NULL) { } Else{myclass_1=NewMyclass_1 (); } } returnMyclass_1;} }
Let's take a look at the most efficient way (what is efficient?). is to try to narrow the locked code block without errors), using the DCK double check lock mechanism to solve
The code is as follows:
PackageSingleton; Public classMyclass_1 {Private StaticMyclass_1 Myclass_1; Privatemyclass_1 () {} Public Staticmyclass_1 getinstance () {if(myclass_1!=NULL) { } Else { synchronized(Myclass_1.class) {
Judge againif(myclass_1==NULL) {Myclass_1=NewMyclass_1 (); } } } returnMyclass_1;} }
Welcome to visit my personal website
Www.fanwencong.com
Java design Pattern--Singleton mode