单例模式

138 阅读1分钟

1. 单例模式-静态常量

public class Singleton {

    private static Singleton singleton = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return singleton;
    }
}

2. 单例模式-静态代码块

public class Singleton {

    private static Singleton singleton;

    static {
        singleton = new Singleton();
    }

    private Singleton() {}

    public static Singleton getInstance() {
        return singleton;
    }
}

3. 单例模式-静态内部类

public class Singleton {

    private static class SingletonInner {

        private static Singleton singleton = new Singleton();
    }

    private Singleton() {}

    public static Singleton getInstance() {
        return SingletonInner.singleton;
    }
}

4. 单例模式-同步方法

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    synchronized public static Singleton getInstance() {
        if (singleton == null) {
            singleton = new Singleton();
        }
        return singleton;
    }
}

5. 单例模式-同步代码块

public class Singleton {

    private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        synchronized (Singleton.class) {
            if (singleton == null) {
                singleton = new Singleton();
            }
        }
        return singleton;
    }
}

6. 单例模式-DCL双检锁

public class Singleton {

    volatile private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

7. 单例模式-枚举

public enum SingletonEnum {

    SINGLETON;

    private Object singleton;

    SingletonEnum() {
        singleton = new Object();
    }

    public Object getInstance() {
        return singleton;
    }
}

8. 单例被序列化反序列化破坏

public class Singleton implements Serializable {

    private static final long serialVersionUID = -7084416999763919708L;

    volatile private static Singleton singleton;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        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();
        }
    }
}
  • 上面代码执行后发现 Singleton 实例不是同一个,因为默认情况下,序列化会通过反射的方式调用无参构造方法创建一个新对象

  • 在 Singleton 类中定义 readResolve() 方法,并实现生成对象的策略,即可防止单例被破坏

学自《Java多线程编程核心技术》