定义:
一个类只有一个实例,所有调用就使用同一个对象
特点:
- 单例类只有一个实例对象
- 单例对象必须由单例类自行创建
- 单例类对外提供一个访问该单例的全局访问点
实现:
- 私有构造方法
- 私有静态引用指向自己实例
- 以自己实例为返回值的公有静态方法
懒汉式:需要的时候才去实例化,不需要我就不实例化。
- 不加锁
- 优点:需要的时候才会实例化变量,实现懒加载(资源利用率高)
- 缺点:线程不安全
- 同步锁
- 优点:线程安全,懒加载
- 缺点:方法进行同步效率太低
- 双重锁
- 优点:线程安全,延迟加载,懒加载
- 缺点:方法进行同步效率太低
//单锁
class Singleton private constructor(){
companion object {
private var instance: Singleton? = null
get() {
if (field != null) {
return field
}
return Singleton()
}
@synchronized //线程安全
fun get(): Singleton {
return instance!!
}
}
}
//双重锁
class Singleton private constructor(){
companion object {
@JvmStatic
val instance: Singleton by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED){
Singleton ()
}
}
}
饿汉式:在类初始化的时候就创建了实例,所以不管用不用都创建了实例,但是是线程安全的,因为静态变量的创建,在类的初始化过程中是保证线程安全的。
- 优点:线程安全,读取变量速度快
- 缺点:因为一开始就创建了变量,如果后面没用到,就有可能浪费资源
object Singleton
静态内部类:在单例类被装载时并不会立即实例化,而是在需要实例化时,调用实例方法,才会装载静态内部类,从而完成Singleton的实例化。
class Singleton private constructor() {
companion object{
val instance = Holder.holder
}
object Holder {
val holder = Singleton()
}
}
其他方式:请参考:https://blog.csdn.net/shylogo/article/details/107388234
优缺点:
优点
- 单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例(减速少内存开销)
- 单例模式可以避免对资源的多重占用
- 因为类控制了实例化过程,所以类可以灵活更改实例化过程。
缺点
- 不能继承,可扩展性差
- 与单一职责原则冲突。
- 不能分场景保存不同数据
- 单例对象长时间不使用,会被系统清理,这些调用对象取数据时会有空
- 如果不及时清理,容易发现内存泄漏
使用场景:
- 需要频繁的进行创建和销毁的对象
- 创建对象时耗时过多或耗费资源过多,但又经常用到的对象
- 工具类对象
- 频繁访问数据库或文件的对象