1. Hungry Chinese style singleton
Copy the code code as follows:
public class Singleton {
private final static Singleton INSTANCE = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return INSTANCE;
}
}
2. With the help of internal classes
It is a lazy singleton because the Java mechanism stipulates that the internal class SingletonHolder will only be loaded (implemented lazy) when the getInstance() method is called for the first time, and its loading process is thread-safe. The instance is instantiated once when the internal class is loaded.
Copy the code code as follows:
public class Singleton {
private Singleton() { }
private static class SingletonHolder {
private final static Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
3. Ordinary locking solution
Copy the code code as follows:
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Although the thread safety problem is solved, every thread calling getInstance must be locked. We want to lock only the first time getInstance is called. Please see the double detection solution below.
4. Double detection, but pay attention to the writing method
Copy the code code as follows:
public class Singleton {
private static Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
Singleton temp = instance;
if(temp == null) {
temp = new Singleton();
instance=temp
}
}
}
return instance;
}
}
Due to the problem of instruction reordering, it cannot be written directly 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 the instance variable is modified with volatile, it will be fine. If it is modified with volatile, it can ensure that the corresponding instructions of instance = new Singleton(); will not be reordered. The following singleton code is also thread-safe:
public class Singleton {
private static volatile Singleton instance = null;
private Singleton() { }
public static Singleton getInstance() {
if(instance == null) {
synchronzied(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}