设计模式之单例模式

单例模式

简介:单例模式是GoF23种设计模式中最常见的设计模式之一,无论是第三方类库,还是我们日常开发中都能看到他的影子。
单例与多例:
单例与多例问题是指,当多个用户访问某个类时,系统是为每个用户创建一个该类实例,还是整个系统无论多少用户访问,只创建一个该类实例。
线程安全问题是指,多个用户同时在访问同一个程序时,其对于某一数据的修改,会不会影响到其他用户中的该数据。若没有影响,则是线程安全的;若有可能影响,则是线程不安全的。

一、饿汉式

public class Singleton {
    /**
     * 在定义变量时候直接初始化对象
     */
    private static Singleton singleton = new Singleton();

    /**
     * 私有构造不允许外部  new
     */
    private Singleton() {
    }

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

饿汉式在类创建时就创建好了一个静态的对象提供系统使用,以后不再改变,能够百分百地保证singleton实例的唯一性。也就是说singleton在多线程的情况下不可能被实例化两次,但是singleton被ClassLoader加载后如果很长时间才被使用,如果一个类中的成员属性很多那么就会占用内存资源。

二 、懒汉式

public class Singleton {
    /**
     * 定义变量但是不直接初始化对象
     */
    private static Singleton singleton = null;

    /**
     * 私有构造不允许外部  new
     */
    private Singleton() {
    }

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

所谓的懒汉式方式就是在使用类的时候再去创建,这样就避免了类在初始化前提前创建—懒加载。但是这种方式在多线程下会出现问题,在多线程下可能出现多个实例。

三 、Volatile+Double-check
Volatile+Double-check 双重检测,它提供了一种高效的数据同步策略,那就是是首次初始化加锁,之后允许多个线程同时进行getInstance方法的调用,Volatile对变量对修饰可以禁止指令重排序,可以防止实例化资源时候出现空指针。

public class Singleton {
    /**
     * 定义变量但是不直接初始化对象
     * 使用volatile修饰可以禁止指令冲排序
     */
    private static volatile Singleton singleton = null;

    /**
     * 私有构造不允许外部 ---- new
     */
    private Singleton() {
    }

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

四 枚举方式

public class Singleton {
    private Singleton() {}
    static enum SingletonEnum {
        //创建一个枚举对象,该对象天生为单例
        INSTANCE;
        private Singleton instance;

        /**
         * 私有化枚举的构造函数
         */
        private SingletonEnum() {
            instance = new Singleton();
        }
        public Singleton getInstance() {
            return instance;
        }
    }
    /**
     * 对外暴露一个获取User对象的静态方法
     */
    public static Singleton getInstance() {
        return SingletonEnum.INSTANCE.getInstance();
    }
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1==instance2);
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值