美文网首页
单例模式

单例模式

作者: SlowGO | 来源:发表于2019-07-22 14:04 被阅读0次

    Java实现单例模式的几种常用方式:

    1. 饿汉式

    实现最简单,缺点是没有使用时就创建,浪费内存。

    public class SingletonHungry {
        private static final SingletonHungry INSTANCE = new SingletonHungry();
    
        private SingletonHungry() {
        }
    
        public static SingletonHungry getInstance() {
            return INSTANCE;
        }
    }
    

    2. 懒汉式 线程安全

    获取对象时再实例化,为了保证线程安全,使用 synchronized 关键字进行同步,缺点是方法级的同步使效率较低。

    public class SingletonLazy {
        private static SingletonLazy instance;
    
        private SingletonLazy() {
        }
    
        public static synchronized SingletonLazy getInstance() {
            if (instance == null) {
                instance = new SingletonLazy();
            }
            return instance;
        }
    }
    

    3. 双重检验锁

    为了提升懒汉式的效率,方法体上的锁去掉,先判断是否已经实例化看,如果没有,在真正创建对象时加锁,进入锁后还有一次判断,这是因为在多线程并发条件下,一个线程拿到锁执行实例化操作,其他线程等待,唤醒后,需要先判断是否已经创建完成了,防止多次创建。

    public class SingletonDoubleCheck {
        private volatile static SingletonDoubleCheck singleton;
    
        private SingletonDoubleCheck (){}
    
        public static SingletonDoubleCheck getSingleton() {
            if (singleton == null) {
                synchronized (SingletonDoubleCheck.class) {
                    if (singleton == null) {
                        singleton = new SingletonDoubleCheck();
                    }
                }
            }
            return singleton;
        }
    }
    

    4. 静态内部类

    此方式是通过类加载机制保证单例,虚拟机会保证类构造器在多线程环境下被正确的加锁、同步,如果多个线程同时去初始化一个类,只会有一个线程执行构造器,其他线程都要等待。

    public class SingletonStaticInnerClass {
        private static class SingletonHolder {
            private static final SingletonStaticInnerClass INSTANCE = 
                    new SingletonStaticInnerClass();
        }
    
        private SingletonStaticInnerClass (){}
    
        public static final SingletonStaticInnerClass getInstance() {
            return SingletonHolder.INSTANCE;
        }
    }
    

    5. 枚举

    用法简单,还可以方式反射方式创建多个实例,是JDK1.5以后才支持的。

    public enum SingletonEnum {
    
        Instance;
        
        private SingletonEnum() {
            System.out.println("init ... ");
        }
    
        public static void main(String[] args) {
    
            SingletonEnum b1 = SingletonEnum.Instance;
            SingletonEnum b2 = SingletonEnum.Instance;
            SingletonEnum b3 = SingletonEnum.Instance;
            
            System.out.println(b1 == b2);
            System.out.println(b1 == b3);
        }
    }
    

    相关文章

      网友评论

          本文标题:单例模式

          本文链接:https://www.haomeiwen.com/subject/dmtwlctx.html