美文网首页iOS小白的笔记
设计模式之——单例模式

设计模式之——单例模式

作者: 齐舞647 | 来源:发表于2017-05-16 20:47 被阅读1次

单例模式:Singleton Pattern


原话:Ensure a class has only one instance ,and provide a global point of access to it.
直译:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

1. 定义:一个类只能产生一个对象。(我是皇帝我独苗)
2. 方法:把该类的构造函数设置为private(私有访问),外部无法访问该构造函数 且又没有办法调用系统默认构造函数,就可以禁止外部创建对象。
3. 示例类图:
单例模式通用类图
4. 示例代码:
class Singleton{
    private static final Singleton singleton = new Singleton();
    //限制产生多个对象
    
    private Singleton(){
        //构造函数
    }
    
    //通过该方法获得实例对象
    public static Singleton getSingleton(){
        return singleton;
    }
    
    //其他方法,尽量是static
    public static void doSomeThing(){
        //...
    }
}
5. 优点:

1.只有一个实例,减少了内存开支
2.减少了系统的性能开销
3.避免了对同一个资源文件的同时写操作
4.可以在系统内设置全局访问点,优化和共享资源访问,负责所有数据表的映射处理

6. 缺点:

1.没有借口,扩展很困难
2.对测试不利,单例模式没有完成,不能进行测试
3.与单一职责有冲突,一个类应该只实现一个逻辑,而不关心它是否是单例的

7. 应用场景:

1.要一个类有且仅有一个对象
2.需要一个共享访问点或共享数据
3.创建一个对象需要的资源过多
4.需要定义大量的静态常量和方法

8. 注意事项:

在高并发的情况下,需要考虑单例模式的线程同步问题,
可能会出现两个对象,破坏了最初的预期

9. 双重检验加锁:强化单例加锁
//强化单例:
public static Singleton getInstance(){
    if(instance == null){
        synchronized (Singleton.class){
            if(instance == null){
                instance = new Singleton();
            }
        }
    }
    return instance;
}
  • 线程1进入方法体,满足条件instance == null,进入synchronized块
  • 线程间抢占cpu资源,线程1被线程2预占,线程2进入方法体
  • 此时方法还没执行完,对象还没有创建出来instance依然为null
  • 线程2试图获取锁资源,但线程1持有该锁,于是线程2阻塞,线程2被线程1预占
  • 线程1继续执行,此时instance 仍然为null,创建Singleton实例并将其引用赋值给instance,方法返回该实例对象的引用,退出方法
  • 线程1被线程2预占,线程2获取锁并检查 instance是否为 null.由于instance 已经被赋值,所以不会创建第二个 Singleton 对象.
  • 这样一套双重检查加锁机制实现了比普通单例模式更高效率的逻辑

其中,双重检索加锁:参考了某位简书博主

相关文章

网友评论

    本文标题:设计模式之——单例模式

    本文链接:https://www.haomeiwen.com/subject/hbqrxxtx.html