单例模式实现方式及理解
二十三种设计模式分类
创建型设计模式
和对象的创建有关,共5种:
单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式。
结构型设计模式
解决模块之间的耦合问题,共7种:
适配器模式,装饰者模式,代理模式,外观模式,桥接模式,组合模式,享元模式。
行为型设计模式
处理类或者对象如何交互,如何分配职责,11种:
策略模式,模板方法模式,观察者模式,迭代器模式,责任链模式,命令模式,备忘录模式,状态模式,访问者模式,中介者模式,解释器模式。
单例模式特点
对外只提供一个唯一的实例对象。
实现思路
- 构造方法private化
- 一个类只有一个实例对象
- 对外提供一个获取本类实例的静态方法
常见实现方式
饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance(){
return instance;
}
}
类加载时,就完成了初始化;无论用不用,先把碗装满了,免得饿着了
懒汉式(线程不安全)
public class Singleton {
private static Singleton instance ;
private Singleton() {
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
只有在使用的时候,才去初始化。多线程的时候,由于没有加锁,有可能会生成的对象不唯一,多线程不安全。
懒汉式(线程安全)
public class Singleton {
private static Singleton instance ;
private Singleton() {
}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
由于加上了锁,多线程中可以很好的工作,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,大部分时候我们是用不到同步的,浪费开销。
双重检查式
public class Singleton {
private static Singleton instance ;
private Singleton() {
}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
对singleton进行了两次判空,第一次是为了不必要的同步,第二次是在singleton等于null的情况下才创建实例。
静态内部类式
public class Singleton {
private Singleton() {
}
private static class SingleTonHolder{
private static final Singleton sInstance = new Singleton();
}
public static Singleton getInstance(){
return SingleTonHolder.sInstance;
}
}
第一次加载Singleton类时并不会初始化sInstance,只有第一次调用getInstance方法时虚拟机加载SingletonHolder 并初始化sInstance ,这样不仅能确保线程安全也能保证Singleton类的唯一性,所以推荐使用静态内部类单例模式。
单例的使用场景
- Application中getInstance()
- 收集信息收集AppInfoOperateProvider
- crash信息收集crashHandler
- 打点功能
- ……