手记

设计模式之单例模式

单例模式的最佳实践

好记性不如烂笔头,总结一下自己印象深刻的设计模式,从最简单的单例模式开始吧!

简介

单例模式(Singleton Pattern) 是最简单的设计模式之一了,这种类型的设计模式属于创建者模式,这种模式是为了确保只有一个对象被创建。

特点

  1. 单例类只能有一个实例
  2. 单例类必须自己创建自己的唯一实例
  3. 单例类必须给其他对象提供着一种实例

优点

  1. 内存中只有该类的一个实例,避免全局使用的类频繁的创建销毁,浪费系统资源。
  2. 避免对资源的多重占用(写文件操作,避免对文件多重占用)。

缺点
没有接口,不能继承,与单一职责冲突,一个类应该只关心内部逻辑,不关心外面怎样实例化。

几种最佳实践

1.饿汉模式

优点:线程安全,不加锁,执行效率高。

缺点:类装载时实例化, 不能保证lazy load 效果,浪费内存。

注意

  1. 基于 classloder 机制避免了多线程的同步问题
  2. 如果调用 getInstance 方法时导致类加载,满足lazy load 载效果。

代码

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton(){}
    public static getInstance(){
        return instance;
    }
}

2. 懒汉模式(double-checked locking)

优点 lazy load,线程安全且保持高性能

缺点 ,实现较复杂

代码

public class Singleton {
    // volatile 保证 new 原子性
    private volatile static Singleton instance;
    private Singleton (){}
    public static Singleton getInstance() {
    // 双校验
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

3. 静态内部类模式

优点:lazy, 线程安全,实现简单,跟双检锁方式效果效果相同

注意
利用 classloder 机制保证初始化一个instance只有一个线程。

代码

public class Singleton {
    private Singleton(){}
    // 静态内部类
    private static class SingletonFactory {
        peivate static final Singleton INSTANCE = new Singleton();
    }
    public static final Singleton getIntance() {
        return SingletonFactory.INSTANCE;
    }
}

4. 枚举

优点:线程安全,简洁,自动支持序列化机制,绝对防止多次序列化,防止反序列化重新创建新的对象。

缺点: no lazy, 不能通过 reflection attack 调用私有构造。

代码

public enum Singleton {
    INSTANCE;
    public void whateverMethod() {
    }
}
总结

经验之谈:

  1. 建议使用 1.饿汉模式 加载
  2. 明确需要 lazy load 使用 3.内部类模式
  3. 涉及反序列化创建对象,使用 4.枚举
  4. 有其他需求,考虑 2.双检锁懒汉模式
1人推荐
随时随地看视频
慕课网APP