设计模式之----单例模式

1. 定义

一个类仅有一个实例,并且自行实例化,向整个系统提供。

关键点:

  • 仅有一个实例
  • 自己创建该实例
  • 能够给调用者提供仅有的实例

2. 单例的实现方式

单例实现从以下几个方面来对比

  1. 是否能够在使用时加载?
  2. 线程是否安全?
  3. 是否易用、易理解?

2.1 饿汉式

类加载时创建自身实例,线程安全。

    /**
     * 饿汉式
     * 1. 不能在使用时才加载:如果该单例较耗资源,那么性能问题会比较突出
     * 2. 线程安全
     * 3. 易用、易理解
     * Created by Administrator on 2017/10/10.
     */

    public class SingleInstance {
        // 初始化时自动创建自身的实例
        private static SingleInstance instance = new SingleInstance();
        // 私有构造方法
        private SingleInstance(){}

        // 简单工厂模式
        public static SingleInstance getInstance(){
            return instance;
        }
    }

2.2 懒汉式

在需要使用时才去创建自身实例,属于懒加载,但是线程不安全。

/**
 * 懒汉式
 * 1. 懒加载
 * 2. 线程不安全,不能用在多线程中
 * 3. 易用、易理解
 * Created by Administrator on 2017/10/10.
 */

public class SingleInstance {

    private static SingleInstance instance;
    // 私有构造方法
    private SingleInstance(){}

    public static SingleInstance getInstance(){
        // 延迟加载
        if (instance == null){
            instance = new SingleInstance();
        }
        return instance;
    }
}
2.2.1 懒汉式进阶(synchronized)

在方法上加同步锁

/**
 * synchronized进阶
 * 1. 懒加载
 * 2. 线程安全,但是性能较低
 * 3. 易用、易理解
 */
public synchronized static SingleInstance getInstance(){
    // 延迟加载
    if (instance == null){
        instance = new SingleInstance();
    }
    return instance;
}
2.2.2 懒汉式进阶(DCLSingleInstance:双重检查锁定)

在懒汉式的基础上

  1. 去掉方法上的同步锁synchronized
  2. 在非空判断中加同步锁,保证性能
  3. 在同步代码中再进行非空判断,进行第二重检查保证不会创建出第二个对象。
  4. 给instance加上volatile修饰符(高并发时使用需要):volatile关键字能禁止指令重排序,比如线程1创建了实例,intance被修改时会被强制写到主存,其他线程也能实时获取到该值。请参考:volatile参考
/**
 * DCL懒加载
 * 1. 懒加载
 * 2. 线程安全,性能较高
 * 3. 易用、易理解
 * Created by Administrator on 2017/10/10.
 */

public class SingleInstance {

    private volatile static SingleInstance instance;
    // 私有构造方法
    private SingleInstance(){}

    public static SingleInstance getInstance(){
        // 延迟加载
        if (instance == null){
            // 第一重锁定
            synchronized (SingleInstance.class){
                //第二重锁定
                if (instance == null){
                    instance = new SingleInstance();
                }
            }

        }
        return instance;
    }
}
2.2.3 懒汉式进阶(静态内部类)
  1. 私有构造方法
  2. 在静态内部类中声明一个静态变量,并创建单例对象
  3. 在提供单例的静态方法中调用返回静态内部类中创建的单例对象
/**
 * 静态内部类
 * 1. 懒加载
 * 2. 线程安全,性能好
 * 3. 易用、易理解
 * Created by Administrator on 2017/10/10.
 */

public class SingleInstance {

    // 私有构造方法
    private SingleInstance(){}

    private static class SingleInner{
        // 在静态内部类中创建单例的对象
        private static SingleInstance instance = new SingleInstance();
    }
    // 在调用该方法时,才会初始化instance
    public static SingleInstance getInstance(){
        return SingleInner.instance;
    }
}

3. 懒汉式和饿汉式

  • 懒汉式:类一加载,单例就已经初始化完成。
  • 饿汉式:只有在使用时才去创建单例的对象。

3.1 线程安全

判断线程是否安全:有没有可能创建多个instance?

  • 懒汉式是线程安全的
  • 饿汉式需要不同的处理才能保证线程安全。

3.2 性能

假如单例需要占用的内存较多,那么要优先使用可以懒加载的懒汉式单例。

说明:

单例还有枚举方式,由于用的较少,此处不再赘述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值