前言:
Android 的设计模式系列文章,欢迎star,持续更新。。。
单例介绍:某个类只有一个实例,并且自行实例化并向整个系统提供这个唯一实例。
多种单例创建模式介绍:
(一) 饿汉式:
public class Singleton {
//饿汉式
private Singleton() { //使用private 是为了防止外部new 多个singleton对象
}
private final static Singleton singletion = new Singleton(); //直接生成一个类的对象
public static Singleton getSingletion() {
return singletion;
}
//优点:写法简单,线程安全
//缺点:没有懒加载的效果,在没有使用到该类的时候会造成内存浪费
}
(二) 懒汉式:
public class Singleton {
//懒汉式
private Singleton() { //使用private 是为了防止外部new 多个singleton对象
}
private static Singleton singletion = null; //声明一个null 对象
/**
* 优点:实现了懒加载
* 缺点:线程不安全
* @return
*/
public static Singleton getSingletion1() { // 在第一个获取的时候才实例化
if (singletion == null) {
singletion = new Singleton();
}
return singletion;
}
/**
* 加一个 synchronized 关键字,达到同步效果
* 优点: 实现了懒加载,线程安全
* 缺点:使用synchronized会造成不必要的同步开销,而且大部分时候我们是用不到同步的。
* @return
*/
public static synchronized Singleton getInstance2() {
if (singletion == null) {
singletion = new Singleton();
}
return singletion;
}
}
(三)双重检查锁定:
public class Singleton {
//双重检查锁定
private Singleton() { //使用private 是为了防止外部new 多个singleton对象
}
//volatile 能够防止代码的重排序,保证得到的对象是初始化过
private volatile static Singleton singleton;
/**
* 双重锁检测
* 优点:懒加载,线程安全,执行效率高
* 缺点:volatile影响一点性能,高并发下有一定的缺陷,某些情况下DCL会失效,虽然概率较小
* @return
*/
public static Singleton getInstance(){
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
(推荐使用) 静态内部类:
public class Singleton {
// 静态内部类
private Singleton() { //使用private 是为了防止外部new 多个singleton对象
}
/**
* 第一次调用的时候才加载SingletonViewHolder并初始化singleton
*
* @return
*/
public static Singleton getInstance() {
return SingletonViewHolder.singleton;
}
/**
* 静态内部类
*/
private static class SingletonViewHolder {
private final static Singleton singleton = new Singleton();
}
}
单例使用场景(优点):
- 本质是控制实例的数量
- 频繁访问数据库或文件的对象
- 工具类对象
- 创建对象时耗时过多或耗费资源过多,但又经常用到的对象
(缺点)
- 获取对象时不能用new
- 单例对象如果持有Context,那么很容易引发内存泄露
- 单例模式一般没有接口,扩展很困难,若要扩展,只能修改代码来实现