单例模式作为设计模式之一,使用场景非常多。本文讲述了Android实现单例模式的几种方式
一.饿汉式
public class SingletionStarving {
private static final SingletionStarving mInstance = new SingletionStarving();
private SingletionStarving() {
}
public static SingletionStarving getInstance() {
return mInstance;
}
}
- 构造函数用private修饰,外部无法访问
- 声明静态对象时就初始化
- static关键字修饰,静态变量,存储在内存中,只有一份数据。
- final关键字,只初始化一次,所以mInstance实例只有一个。
二.懒汉式
public class SingletionSlacker {
private static SingletionSlacker mInstance;
private SingletionSlacker() {}
public static synchronized SingletionSlacker getInstance() {
if (mInstance == null) {
mInstance = new SingletionSlacker();
}
return mInstance;
}
}
- 构造函数用private修饰,外部无法访问
- 使用的时候即调用getInstance的时候才初始化
- static关键字修饰,静态变量,存储在内存中,只有一份数据。
- synchronized线程安全,多线程情况下单例的唯一性
- 缺点:没次调用getInstance都会同步一次,浪费资源
三.双重检查加锁方式
网上建议和使用最多的方法
public class Singletion {
private static Singletion mInstance;
private Singletion() {}
public static Singletion getmInstance() {
if (mInstance == null) {
synchronized (Singletion.class) { if (mInstance == null) {
mInstance = new Singletion (); }
}
}
return mInstance;
}
}
- 构造函数用private修饰,外部无法访问
- 使用的时候即调用getInstance的时候才初始化
- static关键字修饰,静态变量,存储在内存中,只有一份数据
- synchronized线程安全,多线程情况下单例的唯一性
- 两次判断空,避免多次同步(synchronized)
缺点
private static Singletion mInstance;
private Singletion() {}
public static Singletion getmInstance() {}
由于jvm特性,允许乱序执行,上面三句代码顺序不定,那么就可能出现失效的问题。
步骤一、倘若A线程执行getmInstance(),还没执行构造方法Singletion()
步骤二、此时B线程调用getmInstance()。因为A已经执行getmInstance(),所以mInstance不为空就直接获取。
步骤三、由于B直接获取,而真实情况是A线程构造方法还未执行,所以mInstance就为空了。
虽然此情况发生概率较小,但也是一种情况。为了解决这种情况,java1.6开始加入volatile关键字
private volatile static Singletion mInstance;
这样就避免了方式失效的情况。虽然会volatile消耗一些性能,所以最佳写法
public class Singletion {
private volatile static Singletion mInstance;
private Singletion () {}
public static Singletion getmInstance() { if (mInstance == null) {
synchronized (Singletion.class) { if (mInstance == null) {
mInstance = new Singletion(); }
}
}
return mInstance;
}
}
虽然volatile让方式完美,但是没有volatile关键字的写法基本能满足绝大部分情况。除非你要运行在高并发,或者java1.6之前的代码中。
四.静态内部类方式
public class SingletionInternalClass {
private SingletionInternalClass() {}
public static SingletionInternalClass getInstance() {
return SingletionInternalClassHolder.instance;
}
private static class SingletionInternalClassHolder {
private static final SingletionInternalClass instance = new SingletionInternalClass();
}
}
构造函数用private修饰,外部无法访问
使用的时候即调用getInstance的时候才初始化
调用getInstance才回去加载SingletionInternalClassHolder类,确保了线程安全,保证了单例的唯一性
总结
单例模式不管用那种方式实现,核心思想都相同
1、构造函数私有化,通过一次静态方法获取一个唯一实例
2、线程安全
最后推荐使用文中**双重锁方式和静态内部类的方式**来创建单例模式。
以上就是Android 单例模式的四种实现方式的详细内容,更多关于Android 单例模式的实现的资料请关注编程学习网其它相关文章!
本文标题为:Android 单例模式的四种实现方式
基础教程推荐
- Flutter手势密码的实现示例(附demo) 2023-04-11
- Android中的webview监听每次URL变化实例 2023-01-23
- 解决Android Studio突然不显示logcat日志的问题 2023-02-04
- IOS应用内跳转系统设置相关界面的方法 2022-11-20
- IOS 播放系统提示音使用总结(AudioToolbox) 2023-03-01
- iOS开发教程之XLForm的基本使用方法 2023-05-01
- Flutter绘图组件之CustomPaint使用详解 2023-05-12
- Android多返回栈技术 2023-04-15
- Android开发使用RecyclerView添加点击事件实例详解 2023-06-15
- android studio按钮监听的5种方法实例详解 2023-01-12
