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

来源:互联网 发布:网站在线下订单源码 编辑:程序博客网 时间:2024/05/17 03:25

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 性能

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

说明:

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

原创粉丝点击