1. Singleton – Static constant
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton(a) {}
public static Singleton getInstance(a) {
returnsingleton; }}Copy the code
2. Singleton pattern – static code block
public class Singleton {
private static Singleton singleton;
static {
singleton = new Singleton();
}
private Singleton(a) {}
public static Singleton getInstance(a) {
returnsingleton; }}Copy the code
3. Singleton pattern – static inner class
public class Singleton {
private static class SingletonInner {
private static Singleton singleton = new Singleton();
}
private Singleton(a) {}
public static Singleton getInstance(a) {
returnSingletonInner.singleton; }}Copy the code
4. Singleton pattern-synchronous method
public class Singleton {
private static Singleton singleton;
private Singleton(a) {}
synchronized public static Singleton getInstance(a) {
if (singleton == null) {
singleton = new Singleton();
}
returnsingleton; }}Copy the code
5. Singleton mode – Synchronized code blocks
public class Singleton {
private static Singleton singleton;
private Singleton(a) {}
public static Singleton getInstance(a) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = newSingleton(); }}returnsingleton; }}Copy the code
6. Singleton mode -DCL double check
public class Singleton {
volatile private static Singleton singleton;
private Singleton(a) {}
public static Singleton getInstance(a) {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = newSingleton(); }}}returnsingleton; }}Copy the code
7. Singleton mode – Enumeration
public enum SingletonEnum {
SINGLETON;
private Object singleton;
SingletonEnum() {
singleton = new Object();
}
public Object getInstance(a) {
returnsingleton; }}Copy the code
8. Singleton is broken by serialization deserialization
public class Singleton implements Serializable {
private static final long serialVersionUID = -7084416999763919708L;
volatile private static Singleton singleton;
private Singleton(a) {}
public static Singleton getInstance(a) {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = newSingleton(); }}}return singleton;
}
// protected Object readResolve() throws ObjectStreamException {
// return singleton;
/ /}
}
public class Test {
public static void main(String[] args) {
try (FileOutputStream outputStream = new FileOutputStream(new File("Singleton.txt"));
ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {
Singleton singleton1 = Singleton.getInstance();
System.out.println(singleton1.hashCode());
oos.writeObject(singleton1);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try (FileInputStream inputStream = new FileInputStream(new File("Singleton.txt"));
ObjectInputStream ois = new ObjectInputStream(inputStream)) {
Singleton singleton2 = (Singleton) ois.readObject();
System.out.println(singleton2.hashCode());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) { e.printStackTrace(); }}}Copy the code
-
After executing the above code, the Singleton instance is not the same because, by default, serialization creates a new object by calling the no-argument constructor by reflection
-
Defining the readResolve() method in the Singleton class and implementing the policy of generating objects prevents Singleton from being broken
Learn from “Java Multi-threaded Programming Core Technology”