单例模式
单例模式 (Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例模式的结构
单例模式的主要有以下角色
- 单例类。只能创建一个实例的类
- 访问类。使用单例类
单例模式的实现
单例设计模式分为两种:
饿汉式:类加载就会导致该单例实例对象被创建
懒汉式:类加载不会导致该单例实例对象被创建,而是首次使用该对象是才会创建
1.饿汉式:(静态变量方式)
//饿汉式:静态成员变量
class Singleton {
// 1.私有化构造方法
private init() {}
// 2.在本类中创建本类对象
private static let instance = Singleton()
// 3.提供一个公共的访问方式,让外界获取该对象
static func getInstance()->Singleton{
return instance
}
}
测试代码
//创建单例对象
var instance = Singleton.getInstance()
var instance1 = Singleton.getInstance()
print(1)
运行结果
从打印结果可以看出,我们使用的是同于个对象
该方式在成员位置声明singleton类型的静态变量,并创建sinaleton类的对象instance。 instance对象是随着类的加载而创建的。如果该对象足够大的话,而一直没有使用就会造成内存的浪费。
懒汉式-方式1(线程不安全)
//懒汉式 线程不安全
class Singleton {
// 1.私有化构造方法
private init() {}
// 2.声明Singleton类型的变量
private static var instance:Singleton?
static func getInstance()->Singleton{
if instance == nil{ //此处线程不安全需要加锁
instance = Singleton()
}
return instance!
}
}
更改为线程安全的方式swift中@synchronized已经不存在了,可以利用其原理调用了objc_sync中的objc_sync_enter和objc_sync_exit方法来使用
懒汉式-方式2(线程安全)
class Singleton {
// 1.私有化构造方法
private init() {}
// 2.声明Singleton类型的变量
private static var instance:Singleton?
static func getInstance()->Singleton{
objc_sync_enter(instance as Any)//加锁
if instance == nil{//此处线程不安全需要加锁,一般没有必要只是有隐患
sleep(1)
instance = Singleton()
print("创建对象")
}
objc_sync_exit(instance!)//解锁
return instance!
}
}
测试代码
for _ in 0...10{
DispatchQueue.global().async {
_ = Singleton.getInstance()
}
}
测试结果
不加锁
加锁
懒汉式-方式3(双重检查锁)
再来讨论一下懒汉模式中加锁的问题,对于get Instance (〕方法来说,绝大部分的操作都是读操作,读操作是线程安全的,所以我们没必让每个线程必须持有锁才能调用该方法,我们需要调整加锁的时机。由此也产生了一种新的实现模式:双重检查锁模式
class Singleton {
// 1.私有化构造方法
private init() {}
// 2.声明Singleton类型的变量
private static var instance:Singleton?
static func getInstance()->Singleton{
// 第一次判断,如果instance的值不为nil,不需要抢占锁,直接返回对象
if instance == nil{
// 此处进行第二次判断
objc_sync_enter(instance as Any)
if instance == nil{
instance = Singleton()
print("创建对象")
}
objc_sync_exit(instance!)
}
return instance!
}
}
双重检查锁是一种非常好的单例实现模式,解决了单例、性能、线程安全的问题,但是不知道会不会出现类似java的空指针问题(未验证),整体是是完美无缺的一种方式。
懒汉式-方式4(内部类静态变量)
//懒汉式 内部类
class Singleton {
// 1.私有化构造方法
private init() {}
// 2.定义一个内部类
private class SingletonHolder{
// 在内部类中声明并初始化外部类对象
static var instance = Singleton()
}
// 提供公共的访问方式
static func getInstance()->Singleton{
return SingletonHolder.instance
}
}
测试代码
var instance = Singleton.getInstance()
var instance1 = Singleton.getInstance()
运行结果
以上是对应swift的单例模式,记录学习一下吧
感谢黑马程序员课程