几种单例模式

单例模式特征
1、私有的构造方法,不对外开放的
2、通过一个静态方法或者枚举返回单例类到对象
3、注意多线程的场景
4、注意单例类对象在反序列化时不会重新创建对象

几种不同的单例模式:

    1、懒汉式单例,是线程不安全的
    static class Singleton1 {
        // 私有的静态变量
        private volatile static Singleton1 sInstance = null;

        // 私有的构造方法
        private Singleton1() {
            System.out.println("懒汉式单例。。。");
        }

        // 公有的静态方法,是线程不安全的
//        public static Singleton1 getInstance() {
//            if (sInstance == null) {
//                sInstance = new Singleton1();
//            }
//            return sInstance;
//        }

        // 修改为线程安全的,但同步锁粒度太大,很耗性能
//        public static synchronized Singleton1 getInstance() {
//            if (sInstance == null) {
//                sInstance = new Singleton1();
//            }
//            return sInstance;
//        }

        // 双重校验DCL
        public static synchronized Singleton1 getInstance() {
            if (sInstance == null) {
                synchronized (Singleton1.class) {
                    if (sInstance == null) {
                        sInstance = new Singleton1();
                        // 1.给sInstance实例分配对象
                        // 2.调用Singleton1构造方法,初始化成员字段
                        // 3.Singleton1对象赋值sInstance
                        // jdk 乱序 会导致DCL失效 jdk1.5后使用volatile禁止指令重排
                    }
                }
            }
            return sInstance;
        }
    }

    2、饿汉式单例,线程安全
    static class Singleton2 {
        private static Singleton2 sInstance = new Singleton2();

        private Singleton2() {
        }

        public static Singleton2 getInstance() {
            return sInstance;
        }
    }

    3、静态内部类单例,线程安全,并且可以延迟加载
    static class Singleton3 {
        private Singleton3() {
        }

        private static class Holder {
            private static final Singleton3 INSTANCE = new Singleton3();
        }

        public static final Singleton3 getInstance() {
            return Holder.INSTANCE;
        }
    }

    4、枚举类型单例,默认是线程安全的
    static enum Singleton4 {
        INSTANCE;
    }

    5、使用容器
    static class SingletonManager {
        private static Map<String, Object> objMap = new HashMap<>();

        public static void registerService(String key, Object instance) {
            if (!objMap.containsKey(key)) {
                objMap.put(key, instance);
            }
        }

        public static Object getService(String key) {
            return objMap.get(key);
        }
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值