欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

设计模式---单例模式示例代码

程序员文章站 2022-07-13 23:35:04
...

设计模式—单例模式

懒汉式 — 延迟加载

类会被立刻初始化的五种情况:
假设现在有一个A.class
1. A类型实例被创建
2. A类中声明的一个静态方法被调用
3. A类中声明的一个静态成员被赋值
4. A类中声明的一个静态成员被使用并且该成员不是常量成员
5. A类如果是个*类,并且类中有嵌套的断言语句

双重检验模式

import java.io.Serializable;

/**
 * @date 2021/3/18 14:28
 */
public class LazySingleton implements Serializable {

    //volatile 防止类实例化阶段的指令重排序
    //注:类初始化重排序问题:
    // 1:分配内存空间 2:调用构造函数初始化成员变量 3:将变量指向分配的内存空间地址
    //执行顺序可能为 1->2->3 或者 1->3->2
    //volatile可以禁止指令重排序
    private volatile static LazySingleton lazySingleton = null;

    private LazySingleton() {
    	//防止反射调用构造方法进行对象实例化,不能根本性拦截,因为反射可以改变flag值
        if (flag) {
            flag = false;
        } else {
            throw new RuntimeException("禁止反射调用对象实例化");
        }
    }

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

    //当对象被序列化后,在进行反序列化获取时会重新生成一个新的对象
    // readResolve方法再反序列化时被调用返回我们指定要反悔的单例对象
    private Object readResolve () {
        return lazySingleton;
    }

}

静态内部类模式

/**
 * @date 2021/3/18 14:35
 */
public class StaticClassSingleton {

    private StaticClassSingleton () {

    }

    public static class StaticClassSingletonHolder {
        //类被加载时初始化对象,不存在多线程问题,父类被加载是该子类并不会被加载,也实现了延迟加载的功能
        private static StaticClassSingleton staticClassSingleton = new StaticClassSingleton();
    }

    public static StaticClassSingleton getInstance() {
        return StaticClassSingletonHolder.staticClassSingleton;
    }
}

饿汉式

/**
 * @date 2021/3/18 14:34
 */
public class HungerSingleton {

    //类被加载时初始化对象,不存在多线程问题
    private final static HungerSingleton hungerSingleton = new HungerSingleton();

    private HungerSingleton () {

    }

    public static HungerSingleton getInstance() {
        return hungerSingleton;
    }
}

枚举方式

/**
 * @date 2021/3/18 14:43
	枚举方式可以方式反射及序列化对单例模式的破坏
 */
public enum EnumSingleton {

    INSTANCE {
        @Override
        protected Singleton getInstance() {
            if (data == null) {
                synchronized (EnumSingleton.class) {
                   if (data == null) {
                       data = new Singleton();
                   }
                }
            }
            return data;
        }
    };

    protected abstract Singleton getInstance();

    private volatile static Singleton data;

    private static class Singleton {

    }

}

测试类

/**
 * @author wwy
 * @date 2021/3/18 14:38
 */
public class Test {

    public static void main1(String[] args) {
        Object instance11 = LazySingleton.getInstance();
        Object instance12 = LazySingleton.getInstance();
        System.out.println(instance11);
        System.out.println(instance12);
        System.out.println(instance11 == instance12);
    }

    public static void main2(String[] args) {
        Object instance21 = HungerSingleton.getInstance();
        Object instance22 = HungerSingleton.getInstance();
        System.out.println(instance21);
        System.out.println(instance22);
        System.out.println(instance21 == instance22);
    }

    public static void main3(String[] args) {
        Object instance31 = StaticClassSingleton.StaticClassSingletonHolder.getInstance();
        Object instance32 = StaticClassSingleton.StaticClassSingletonHolder.getInstance();
        System.out.println(instance31);
        System.out.println(instance32);
        System.out.println(instance31 == instance32);
    }

    public static void main4(String[] args) {
        Object instance41 = EnumSingleton.INSTANCE.getInstance();
        Object instance42 = EnumSingleton.INSTANCE.getInstance();
        System.out.println(instance41);
        System.out.println(instance42);
        System.out.println(instance41 == instance42);
    }

}

序列化问题验证

import java.io.*;

/**
 * @author wwy
 * @date 2021/3/18 11:06
 */
public class Test {

    public static void main(String[] args) throws Exception {
        HungrySingleton instance = HungrySingleton.getInstance();
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file"));
        oos.writeObject(instance);

        File file = new File("singleton_file");
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
        HungrySingleton newInstance = (HungrySingleton) ois.readObject();

        System.out.println(instance);
        System.out.println(newInstance);

        System.out.println(instance == newInstance);
    }

    private static class HungrySingleton implements Serializable{
        private final static HungrySingleton hungrySingleton = new HungrySingleton();
        public static HungrySingleton getInstance() {
            return hungrySingleton;
        }

    }
}
相关标签: java