The first one is ( lazy , Thread unsafe ):

package Singleton;
/**
* @echo 2013-10-10 lazy Thread unsafe
*/
public class Singleton1 {
private static Singleton1 instance; private Singleton1() {
} public static Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}

This kind of writing lazy loading Obviously , But the fatal thing is that multithreading doesn't work properly .

The second kind ( lazy , Thread safety ):

package Singleton;
/**
* @echo 2013-10-10 lazy Thread unsafe
*/
public class Singleton1 {
private static Singleton1 instance; private Singleton1() {
} public static Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
}

This kind of writing works well in multithreading , And it looks like it has a good lazy loading, however , Unfortunately , Efficiency is very low ,99% There is no need to synchronize .

The third kind of ( The hungry ):

package Singleton;
/**
* @echo 2013-10-10
*
*/
public class Singleton3 {
private static Singleton3 instance = new Singleton3(); private Singleton3() {
} public static Singleton3 getInstance() {
return instance;
}
}

This way is based on classloder The mechanism avoids the synchronization problem of multithreading , however ,instance Instantiate at class load time , Although there are many reasons for class loading , In singleton mode, most of them call getInstance Method , But I'm not sure there are other ways ( Or other static methods ) Causes the class to load , This time initialization instance Obviously not lazy loading The effect of .

A fourth ( hungry han , variant ):

package Singleton;
/**
* @echo 2013-10-10 The hungry , variant
*/
public class Singleton4 {
private static Singleton4 instance = null;
static {
instance = new Singleton4();
} private Singleton4() {
} public static Singleton4 getInstance() {
return instance;
}
}

On the surface, it looks quite different , In fact, the third way is similar , Are instantiated at class initialization instance.

The fifth ( Static inner class ):

package Singleton;
/**
* @echo 2013-10-10 Static inner class
*/
public class Singleton5 {
private static class SingletonHolder {
private static final Singleton5 INSTANCE = new Singleton5();
} private Singleton5() {
} public static final Singleton5 getInstance() {
return SingletonHolder.INSTANCE;
}
}

This approach also takes advantage of classloder To ensure initialization instance There is only one thread , It's different from the third and fourth ways ( A very subtle difference ): The third and fourth way is just to Singleton Class is loaded , that instance It will be instantiated ( Don't reach lazy loading effect ), And this way is Singleton Class is loaded ,instance Not necessarily initialized . because SingletonHolder Class is not actively used , Only display by calling getInstance When the method is used , Load... Will be displayed SingletonHolder class , To instantiate instance. Imagine , If you instantiate instance It's a drain on resources , I want him to delay loading , On the other hand , I don't want to be here Singleton The class is instantiated when it is loaded , Because I can't be sure Singleton Classes may also be actively used elsewhere to be loaded , So this is the time to instantiate instance Clearly not appropriate . This is the time , Compared with the third and fourth methods, this method seems reasonable .

6 kinds of ( enumeration ):

package Singleton;
/**
* @echo 2013-10-10 enumeration
*/
public enum Singleton6 {
INSTANCE;
public void whateverMethod() {
}
}

This way is Effective Java author Josh Bloch Ways to advocate , It not only avoids the multithreaded synchronization problem , It also prevents deserialization from recreating new objects , It's a very strong barrier , however , I think it's due to 1.5 To add enum characteristic , It feels strange to write in this way , In practice , I've rarely seen anyone write that .

Seventh kinds ( Double check lock ):

package Singleton;
/**
* @echo 2013-10-10
* Double check lock 1
*/
public class Singleton7 {
private static Singleton7 instance=null; private Singleton7() {
} public static Singleton7 getSingleton() {
if (instance == null) {
synchronized (Singleton7.class) {
Singleton7 temp=instance;
if (temp == null) {
temp = new Singleton7();
instance=temp;
}
}
}
return instance;
}
}

Due to the reordering of instructions , So it can't be written as follows :

public class Singleton {
private static Singleton instance = null; private Singleton() {
} public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
} }
return instance;
}
}

But if instance Instance variables use volatile It's OK to decorate ,volatile If you decorate it, you can make sure that instance = new Singleton(); The corresponding instructions are not reordered , The following singleton code is also thread safe :

package Singleton;
/**
* @echo 2013-10-10
* Double check lock 2
*/
public class Singleton8 {
private volatile static Singleton8 singleton; private Singleton8() {
} public static Singleton8 getSingleton() {
if (singleton == null) {
synchronized (Singleton8.class) {
if (singleton == null) {
singleton = new Singleton8();
} }
}
return singleton;
}
}

This is an upgrade of the second way , Commonly known as double check lock , For details, please check :

http://www.ibm.com/developerworks/cn/java/j-dcl.html

stay JDK1.5 after , Double check lock can normally achieve single case effect .

summary

There are two problems to pay attention to :

1、 If the singleton is loaded by a different class loader , Then it is possible to have multiple instances of singleton classes . Suppose it's not remote access , For example, some servlet Containers for each servlet Using a completely different class   Loader , So if there are two servlet Access a singleton class , They all have their own examples .

2、 If Singleton Realized java.io.Serializable Interface , Then instances of this class may be serialized and restored . No matter what , If you serialize an object of a singleton class , Next, restore multiple objects , Then you'll have multiple instances of singleton classes .

The way to fix the first problem is :

private static Class getClass(String classname)throws ClassNotFoundException{
ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
if(classLoader==null)
classLoader=Singleton.class.getClassLoader();
return (classLoader.loadClass(classname));
}

The way to fix the second problem is :

public class Singleton implements java.io.Serializable {
public static Singleton INSTANCE = new Singleton(); protected Singleton() {
} private Object readResolve() {
return INSTANCE;
}
}

For me, , I prefer the third and fifth way , Simple and easy to understand , And in JVM Layer implements thread safety ( If it's not a multiple classloader environment ), In general , I'll use the third way , Only if we want to realize lazy loading The fifth way will be used when the effect is , in addition , When it comes to deserialization to create objects, I'll try to use enumeration to implement singletons , however , I always make sure my program is thread safe , And I'll never use the first and second ways , If there are other special needs , I might use a seventh way , After all ,JDK1.5 There's no double check lock problem anymore .

========================================================================

superheizai The students summed it up very well :

But generally speaking , The first is not a single case , The fourth and the third are a kind of , If so , The fifth can also be written separately . So , Generally, there are five ways to write a single example . lazy , Evil man , Double check lock , Enumerations and static inner classes .

I'm happy to have readers like this , Together ' .

Off the coast :

Java Medium volatile keyword

About volatile We know , stay Java Setting the value of a variable in , except long and double All variables of type are atomic operations , in other words , For simple read and write operations of variable values, there is no need to synchronize . This is in JVM 1.2 Before ,Java The memory model implementation of always reads variables from main memory , There is no need for special attention . And with the JVM Mature and optimize , Now in a multithreaded environment volatile The use of keywords becomes very important . In the current Java Memory model , Threads can save variables in local memory ( For example, the machine register ) in , Instead of reading and writing directly in main memory . This may cause a thread to modify the value of a variable in main memory , Another thread continues to use copies of its variable values in registers , Cause data inconsistency . To solve this problem , Just like in this program , Declare the variable as volatile( Unstable ) that will do , This is the instruction JVM, This variable is not stable , Every time I use it, I read it in main memory . As a general rule , In a multitasking environment, the shared flag among tasks should be marked with volatile modification .
 
Volatile Modifies a member variable each time it is accessed by a thread , Both force the value of the member variable to be stressed from Shared memory . and , When a member variable changes , Forces the thread to write the change back to Shared memory . So at any moment , Two different threads always see the same value of a member variable .
Java The language specification states that : To get the best speed , Allow threads to keep private copies of shared member variables , And only when the thread enters or leaves the synchronization code block, it is compared with the original value of the shared member variable .
So when multiple threads interact with an object at the same time , We must pay attention to let the thread get the changes of shared member variables in time .
and volatile Key words are tips VM: You can't save a private copy of this member variable , Instead, interact directly with shared member variables .
Use advice : Use... On member variables accessed by two or more threads volatile. When the variable to be accessed is already in synchronized Block of code , Or constant , No need to use .
Due to the use volatile The shield is off VM The necessary code optimizations in , So the efficiency is relatively low , So be sure to use this keyword when necessary .

Java: Seven ways to write singletons ( Reprint ) More articles about

  1. Java Seven ways to write singletons

    Java Seven ways to write singletons The first one is ( lazy , Thread unsafe ) public class Singleton { private static Singleton instance; private Sin ...

  2. Java The singleton pattern of design pattern ( Seven ways of writing )

    Java The singleton pattern of design pattern ( Seven ways of writing ) The first one is , Slacker type ,lazy initialization , Thread unsafe , It doesn't work in multithreading : public class Singleton { private static Singleto ...

  3. The singleton pattern :Java Several writing methods of singleton pattern and their advantages and disadvantages

    Sum up Java Several ways to write the singleton pattern : 1.  Hungry Chinese style public class Singleton { private static Singleton instance = new Singleton( ...

  4. Android Seven ways to write the single example pattern of design pattern

    One Singleton mode and its application scenarios Singleton mode is the most widely used mode , It's also one of the first design patterns I know . Before we learn more about singleton patterns . Whenever you meet someone like :getInstance() When creating instance code like this , I think of it as a singleton pattern ...

  5. Java: Seven ways to write singletons

    The first one is ( lazy , Thread unsafe ): 1 public class Singleton { 2 private static Singleton instance; 3 private Singleton ( ...

  6. Java: Seven ways to write singletons [ turn ]

    The first one is ( lazy , Thread unsafe ):  1 public class Singleton {   2     private static Singleton instance;   3     privat ...

  7. 【JAVA Study 】 Seven ways to write singletons

    Respect copyright :http://cantellow.iteye.com/blog/838473 The first one is ( lazy . Thread unsafe ): Java Code    public class Singleton { private ...

  8. Java: Seven ways to write singletons < turn >

    The first one is ( lazy , Thread unsafe ):  1 public class Singleton {   2     private static Singleton instance;   3     privat ...

  9. Consider the past you shall know the future (java Realization ) Seven ways to write singletons

    The first one is ( lazy , Thread unsafe ): Java Code public class Singleton { private static Singleton instance; private Singleton ...

Random recommendation

  1. PCA、ZCA An albino

    Whitening is an important pretreatment process , The purpose is to reduce the redundancy of input data , So that the whitened input data has the following properties :(i) The correlation between features is low :(ii) All features have the same variance . Albinism is divided into PCA Albinism and ZCA An albino , In the data ...

  2. Client configuration file tnsname.ora

    ARP2 = (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 182.168.1.173)(PORT = 1521) ...

  3. C# Bubble sort details

    Write a simple bubble sort today , With detailed Chinese Notes , Novices must see ! Because this is a job interview often written examination Questions to be tested . using System; using System.Collections.Generic ...

  4. Ubuntu Search for commands

    Ubuntu Find the folder Use find Command find find / -name Folder name -type d Find the path in the result Search for commands Start at the root to find all the files with the extension .log Text file for , And find out what contains ”ERROR” ...

  5. Spring Boot MyBatis Connect to database

    Busy recently , I didn't have time to MyBatis The integration of , Actually mybatis The official website is 2015 year 11 It was released at the end of the month SpringBoot Integrated Release edition ,Github There's a code on it :https://gi ...

  6. Java BigDecimal Type of Addition, subtraction, multiplication and division

    original text : https://blog.csdn.net/xuwei_net/article/details/81253471 Add :add Subtraction :subtract Multiplication :multiply division :divid ...

  7. istio Environment building for macbook

    First, we need to build docker+k8s Environmental Science , How to build it will not be repeated here , You can search for . Open the command line , Run the command : curl -L https://git.io/getLatestIstio | ISTIO_VER ...

  8. 21 re Regular modules Garbage collection mechanism

    Garbage collection mechanism Data that cannot be accessed by a program , It's called garbage Reference count Reference count : The number of times the memory address used to record the value was recorded : When the reference count of a value is 0 when , This value will be recycled by the garbage collection mechanism of the system Every reference to a value address makes the value ...

  9. About JDBC Batch operation of executeBatch() Caused by sql Statement exception

    java.sql.BatchUpdateException: You have an error in your SQL syntax; check the manual that correspon ...

  10. UVA1479 Graph and Queries

    Ideas Disgusting topic It's similar to the problem of never having a hometown Treap Heuristic merging ideas But because the addition of edges becomes the deletion of edges So it should be processed in reverse order after offline The array needs to be open enough Code #include <cstdio> #include & ...