傲视苍穹iOS《Swift》VIP专题程序猿设计模式

设计模式之单件模式(Singleton Pattern)

2016-08-06  本文已影响283人  六尺帐篷

单件模式,也叫单例模式,可以说是设计模式中最简单的一种。顾名思义,就是创造独一无二的唯一的一个实例化的对象。

为什么要这样做呢?因为有些时候,我们只需要一个对象就够了,太多对象反而会引起不必要的麻烦。比如说,线程池,缓存,打印机,注册表,如果存在多个实例的话,反而会导致许多问题!

引出单例模式

我们通过一个小问题引出单例模式!

public MyClass{
  private MyClass() {}  
}
public MyClass{
  private MyClass() {}  
  public static MyClass getInstance() {
    return new MyClass();
  }
}

经典单例模式的实现

public class Singleton {
    private static Singleton uniqueInstance;
    
    private Singleton(){}
    
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    } 
}

定义单件模式

单件模式的定义: 确保一个类只有一个实例,并提供一个全局访问点。

这定义应该很好理解,我们结合类图说明:

Paste_Image.png

经典单件模式存在的问题

经典单件模式实际中存在这一定的问题,在第一次初始化实例的时候,如果同时有不同的线程访问,那么可能最后不只实例化出一个对象。

Paste_Image.png

如图所示,如果两个线程如图所示的顺序交错执行,那么最后会实例化两个对象!
这就是经典单例模式存在的多线程问题。

解决单例模式的多线程问题

synchronize

显然最简单的一种解决方法就是同步getInstance方法。

public class Singleton {
    private static Singleton uniqueInstance;
    
    private Singleton(){}
    
    public static synchronized Singleton getInstance() {
        if (uniqueInstance == null) {
            uniqueInstance = new Singleton();
        }
        return uniqueInstance;
    } 
}

这样显然可以很好的解决问题,但是同步会降低效率。

急切实例化

public class Singleton {
    private static Singleton uniqueInstance = new Singleton();
    
    private Singleton(){}
    
    public static synchronized Singleton getInstance() {
        return uniqueInstance;
    } 
}

在任何线程访问uniqueInstance变量前,我们保证一定已经创建了这个实例。

双重检查加锁

public class Singleton {
    private volatile static Singleton uniqueInstance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
        return uniqueInstance;
    }
}
上一篇下一篇

猜你喜欢

热点阅读