读单例模式自我理解
来源:互联网 发布:酒店网络销售平台 编辑:程序博客网 时间:2024/06/10 02:48
http://www.runoob.com/design-pattern/singleton-pattern.html
一个单一类,自己负责创建自己,同时确保只有单个对象被创建。提供一个访问其唯一对象的类方法
1. 单例类只能有一个实例。
2. 单例类必须自己创建自己的唯一实例。
3. 单例类必须给所有其他对象提供这一实例
优点:1. 内存中只有一个实例,减少内存开销,尤其是频繁的创建和销毁实例
2. 避免资源多重占用
缺点:没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化
懒汉模式:使用方法时才进行创建,需要考虑线程安全问题
饿汉模式:类创建的同时,已经创建好一个静态的对象供使用。是线程安全的
懒汉单例,线程不安全
1.最简单(非线程安全)
+ (PPLAccountManager*)sharedManager {
if (sharedInstance ==nil) {sharedInstance = [[self alloc]init];
}
return sharedInstance;
}
java类似:
public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
单线程下运行正常,但是在多线程下就有问题了。如果两个线程同时运行到判断shareInstance是否为nil的if语句,且shareInstance没有创建时候,那么2个线程都会创建一个实例,此时单例就不在满足单例模式的要求了。为了保证多线程环境下我们还是只能得到类型的一个实例,需要加上一个同步锁。如下:
2.线程安全(不是最优)
+ (PPLAccountManager*)sharedManager {
@synchronized(self){if (sharedInstance == nil) {
sharedInstance = [[selfalloc]init];
}
return sharedInstance;
}
}
java类似:
public class Singleton { private static Singleton instance; private Singleton (){} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这里还不是很完美。我们还是设想两个线程同时想创建一个实例,由于同一时刻只能有一个能得到同步锁,每当第一个线程锁加上锁,第二个线程只能等待,当第一个线程发现实例还没有创建时,它创建一个实例。接着第一个线程释放同步锁,此时第二个线程可以加上同步锁,并运行接下来的 代码。我们每次得到单例实例,都会试图加上一个线程锁,而加锁是一个非常耗时的操作,在没有必要的时候,我们尽量要避免。
3.线程安全(逻辑复杂)
+ (PPLAccountManager*)sharedManager {
if (sharedInstance == nil) {
@synchronized(self){
if (sharedInstance == nil) {
sharedInstance = [[self alloc]init];
}
}
}
return sharedInstance;
}
public class Singleton { private volatile static Singleton singleton; private Singleton (){} public static Singleton getSingleton() { if (singleton == null) { synchronized (Singleton.class) { if (singleton == null) { singleton = new Singleton(); } } } return singleton; } }
4.最优算法(官方推荐)
+ (PPLAccountManager*)sharedManager {
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
sharedInstance = [[self alloc] init]; });
return sharedInstance;
}
}
- 读单例模式自我理解
- Mvp 模式自我理解
- 单例模式 自我理解
- flex布局模式自我理解
- php设计模式自我理解
- 设计模式之命令模式[自我理解]
- 设计模式-观察者模式自我理解
- 代理模式的自我理解(一)
- 设计模式自我理解_java篇
- 自我理解的KMP 算法 模式匹配
- 23种设计模式 慢慢来 自我理解
- 关于设计模式的自我理解
- 自我理解
- 模式学习的自我理解和疑惑(1)
- 原型模式-浅克隆和深克隆的自我理解
- 观察者模式 (Observer)的自我理解!欢迎指正
- 通过连接池操作 理解装饰者设计模式 自我理解
- 官方aidl 自我理解
- LeetCode题解:Battleships in a Board
- json解析以及datagrid列重复问题
- Android文本广告
- 如何将eclipse导出的doc文档转换为chm格式
- JAVA(2017-02-04)
- 读单例模式自我理解
- Linux C 两种方法实现复制拷贝文件
- 寻找i*j=m的个数(简单模拟)
- QPropertyAnimation 学习笔记7
- JavaScript日期对象-基本操作
- JavaEE jsp的编译指令和动作指令
- 一个人写界面有点写累了
- Golang1.7.4标准库sql使用
- CURL使用