Kotlin 的单例模式(5种)
Kotlin 的5种单例模式:
- 饿汉式
- 懒汉式
- 线程安全的懒汉式
- 双重校验锁式
- 静态内部类式
一、饿汉式实现
特点:在类创建的同时就已经创建好一个静态的对象供系统使用,以后不再改变,所以天生是线程安全的,调用效率高,但是不能延时加载,占用内存。
- Java 的实现
//Java实现
public class SingletonDemo {
private static SingletonDemo instance=new SingletonDemo();
private SingletonDemo(){
}
public static SingletonDemo getInstance(){
return instance;
}
}
- Kotlin的实现
object SingletonDemo
二、懒汉式
特点:在第一次调用的时候实例化自己,没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全。
- Java 的实现
public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
if(instance==null){
instance=new SingletonDemo();
}
return instance;
}
}
- Kotlin 的实现
class SingletonDemo private constructor() {
companion object {
private var instance: SingletonDemo? = null
get() {
if (field == null) {
field = SingletonDemo()
}
return field
}
fun get(): SingletonDemo{
//这里不用getInstance作为为方法名,是因为在伴生对象声明时,内部已有getInstance方法,所以只能取其他名字
return instance!!
}
}
}
三、线程安全的懒汉式
特点:线程安全,调用效率不高,第一次调用才初始化,避免内存浪费,须加锁 synchronized 才能保证单例,但加锁会影响效率。
- Java的实现方式
public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){}
public static synchronized SingletonDemo getInstance(){//使用同步锁
if(instance==null){
instance=new SingletonDemo();
}
return instance;
}
}
- Kotlin的实现方式
class SingletonDemo private constructor() {
companion object {
private var instance: SingletonDemo? = null
get() {
if (field == null) {
field = SingletonDemo()
}
return field
}
@Synchronized
fun get(): SingletonDemo{
return instance!!
}
}
}
四、双重校验锁式(Double Check)
特点:线程安全,这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
- Java 的实现方式
public class SingletonDemo {
private volatile static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
if(instance==null){
synchronized (SingletonDemo.class){
if(instance==null){
instance=new SingletonDemo();
}
}
}
return instance;
}
}
- Kotlin 的实现方式
class SingletonDemo private constructor() {
companion object {
val instance: SingletonDemo by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
SingletonDemo() }
}
}
五、静态内部类式
特点:这是官方推荐的。外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化INSTANCE,故而不占内存。不仅能确保线程安全,也能保证单例的唯一性,同时也延迟了单例的实例化。
- Java的实现方式
public class SingletonDemo {
private static class SingletonHolder{
private static SingletonDemo instance=new SingletonDemo();
}
private SingletonDemo(){
System.out.println("Singleton has loaded");
}
public static SingletonDemo getInstance(){
return SingletonHolder.instance;
}
}
- Kotlin 的实现方式
class SingletonDemo private constructor() {
companion object {
val instance = SingletonHolder.holder
}
private object SingletonHolder {
val holder= SingletonDemo()
}
}