一、饿汉式单例
在 Java 中,饿汉式单例在类加载时就创建实例。
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
在 Kotlin 中:
object EagerSingletonKotlin {
fun doSomething() {
println("Doing something in eager singleton.")
}
}
这是 Kotlin 中的对象表达式实现的单例,类似于 Java 的饿汉式单例,在首次访问该对象所在的类时就会被创建。
二、懒汉式单例(线程不安全)
Java 中的懒汉式单例在第一次被调用时创建实例。
public class LazySingletonUnsafe {
private static LazySingletonUnsafe instance;
private LazySingletonUnsafe() {}
public static LazySingletonUnsafe getInstance() {
if (instance == null) {
instance = new LazySingletonUnsafe();
}
return instance;
}
}
Kotlin 中:
class LazySingletonUnsafeKotlin private constructor() {
companion object {
private var instance: LazySingletonUnsafeKotlin? = null
fun getInstance(): LazySingletonUnsafeKotlin {
if (instance == null) {
instance = LazySingletonUnsafeKotlin()
}
return instance!!
}
}
}
这种实现是线程不安全的,在多线程环境下可能会创建多个实例。
三、线程安全的懒汉式单例(线程安全)
Java 中可以通过同步方法实现线程安全的懒汉式单例。
public class LazySingletonSafe {
private static LazySingletonSafe instance;
private LazySingletonSafe() {}
public static synchronized LazySingletonSafe getInstance() {
if (instance == null) {
instance = new LazySingletonSafe();
}
return instance;
}
}
Kotlin 中:
class LazySingletonSafeKotlin private constructor() {
companion object {
private var instance: LazySingletonSafeKotlin? = null
@Synchronized
fun getInstance(): LazySingletonSafeKotlin {
if (instance == null) {
instance = LazySingletonSafeKotlin()
}
return instance!!
}
}
}
使用 “@Synchronized” 注解确保在多线程环境下的线程安全。
四、双重检查锁单例
Java 中双重检查锁单例:
public class DoubleCheckedLockingSingleton {
private static DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton() {}
public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}
Kotlin 中:
class DoubleCheckedLockingSingletonKotlin private constructor() {
companion object {
@Volatile
private var instance: DoubleCheckedLockingSingletonKotlin? = null
fun getInstance(): DoubleCheckedLockingSingletonKotlin {
if (instance == null) {
synchronized(DoubleCheckedLockingSingletonKotlin::class.java) {
if (instance == null) {
instance = DoubleCheckedLockingSingletonKotlin()
}
}
}
return instance!!
}
}
}
使用 “@Volatile” 关键字确保变量的可见性和禁止指令重排。
五、静态内部类单例
Java 中的静态内部类单例:
public class StaticInnerClassSingleton {
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
private StaticInnerClassSingleton() {}
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Kotlin 中:
class StaticInnerClassSingletonKotlin private constructor() {
companion object {
val instance by lazy {
StaticInnerClassSingletonKotlin()
}
}
}
这种方式利用了 Kotlin 的 “by lazy” 委托属性,实现了类似 Java 静态内部类单例的效果,在第一次访问时才会创建实例,并且是线程安全的。
总结:饿汉式没有延迟加载不推荐,懒汉式跟双重锁写法复杂不推荐,静态内部类写法为最优解!