特点
A private constructor [私有构造函数]
A static reference of its class[当前类的静态引用]
One static method [一个静态方法获取实例]
Globally accessible object reference [允许全局获取]
Consistency across multiple threads [跨线程安全]
存在类型:
1、饿汉模式
直接赋值,用static标志,类加载较慢;
// 饿汉模式:直接进行加载,在类加载时直接进行赋值;
public class Singleton {
// 1. 属性私有化; 2.static关键字获取,类加载时会直接加载;
private static Singleton singleton = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return singleton;
}
}
2、懒汉模式:
使用时再加载
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public static Singleton getInstance() {
// 数据在获取时新建,需要加锁避免线程不安全
synchronized(getInstance()) {
if (singleton == null) singleton = new Singleton();
return singleton;
}
}
}
3、双重检查模式
单例模式的创建&优化过程:
(1)需要在使用这个对象的时候才创建,节省内存;
解决:在调用"提供对象的方法"的时候才创建
(2)可能多线程不安全;
解决:对整个"提供对象的方法"的时候加锁;
(3)锁住整个方法消耗太大了;
解决:双重锁检测机制;
public class Singleton {
// 设置可见性
private volatile static Singleton singleton;
private Singleton() { }
public static Singleton getInstance() {
// 避免锁住当前方法,只在singleton为null需要创建时才枷锁
if (singleton == null) {
synchronized(Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
两次判空解决了什么问题:
第一个判断为空 --> 解决的效率问题,不需要每个线程都拿住锁;
第二个判断为空 --> 防止线程不安全
kotlin使用单例的两种用法:
参考文章: https://blog.mindorks.com/how-to-create-a-singleton-class-in-kotlin
(1)直接使用object;
- kotlin中object是全局静态类,即用object标记的方法全局只存在一个且在放在栈中;
- kotlin中object是可以继承一个class的;
(2)懒加载单例
In early initialization, all the components are initialized in the
Application.onCreate() using the init() functions. But this results in
slowing down the application startup by blocking the main thread. So,
it is generally advised to use the lazy initialization
way.【在初始化时,所有的组件都会在Applicat.onCreate()中实现。但这会阻塞主线程和延迟app启动时间。因此,可以通过懒加载方式实现单例】
open class SingletonHandler<out T: Any>(creator: () -> T) {
private var creator: (() -> T)? = creator
@Volatile
private var instance: T? = null
// 双重检测懒汉式
fun getInstance(): T {
// 直接返回instance,由于instance可为空,会报错;
val resInstance = instance
if (resInstance != null) return resInstance
return synchronized(this) {
val res = instance
if (res != null) {
res
} else {
val created = creator!!()
instance = created
creator = null
created
}
}
}
}
class MySingleton private constructor() {
// 初始化时懒加载, 使用
companion object: SingletonHandler<MySingleton>(::MySingleton) {
}
}
获取方式:
class Test() {
fun test() {
val mySingleton = MySingleton.getInstance()
}
}