Java 单例

Doule Check 方式

/**
 * double check
 * 如果没有 synchronized 和 二次 checkNull 在单线程中没有任何问题。
 * synchronized 保证只能有一个线程进入方法体中,其他的线程会进入等待队列。
 * [_instance = new JavaTest()] 流程为: new 写入缓存 -> 更新到主存中,
 * 
 * 为了防止中间过程被打断需要为变量添加 volatile 
 * 
 * volatile 可以保证数据的可见行,即数据直接会更新更新到主存中,其他线程都可以看到。
 * 避免出现当前线程只是更新了缓存中的数据,而没有更新到主存中,在单例中就会导致其他线程再次创建实例,
 * 这样就违反了单例的本质。
 */
private static volatile JavaTest _instance;

public static JavaTest getInstance() {
    if (_instance == null) {
        synchronized (JavaTest.class) {
            if (_instance == null) {
                _instance = new JavaTest();
            }
        }
    }
    return _instance;
}
2. 根据classload原理直接创建静态实例
public class Singleton {  
    private static Singleton instance = null;  
    static {  
      instance = new Singleton();  
    }  
    private Singleton (){}  
    public static Singleton getInstance() {  
        return instance;  
    }  
} 
  1. 使用枚举的方式
    其实这种方式和上面的方式基本相同,枚举类在编译后其实也是把内部的每个枚举形成对应的静态实例,相比第一种double-check方式缺少了lazy load
static enum SingletonEnum {
    INSTANCE;

    private JavaTest javaTest;

    private SingletonEnum() {
        javaTest = new JavaTest();
    }

    public JavaTest getInstance() {
        return javaTest;
    }
}

public static JavaTest getInstance2() {
    return SingletonEnum.INSTANCE.getInstance();
}
  1. 使用静态内部类的方式,这种方式也可以实现懒加载(在Dagger和Hilt使用Singleton注入的类就是使用这种方式进行单例的实现的)

public class Singleton {
// 静态内部类
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}

public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
}  

}
kotlin 单例

companion object {
val instance: KotlinTest by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
kotlinTest()
}
}
lazy 可以实现懒加载

LazyThreadSafetyMode.SYNCHRONIZED 对应下面的方法:

private class SynchronizedLazyImpl(initializer: () -> T, lock: Any? = null) : Lazy, Serializable {
private var initializer: (() -> T)? = initializer
// 这里同样适用了Volatile 来保持可见性
@Volatile private var _value: Any? = UNINITIALIZED_VALUE
// final field is required to enable safe publication of constructed instance
private val lock = lock ?: this

override val value: T
    get() {
        val _v1 = _value
        if (_v1 !== UNINITIALIZED_VALUE) {
            @Suppress("UNCHECKED_CAST")
            return _v1 as T
        }

        return synchronized(lock) {
            val _v2 = _value
            if (_v2 !== UNINITIALIZED_VALUE) {
                @Suppress("UNCHECKED_CAST") (_v2 as T)
            } else {
                val typedValue = initializer!!()
                _value = typedValue
                initializer = null
                typedValue
            }
        }
    }

override fun isInitialized(): Boolean = _value !== UNINITIALIZED_VALUE

override fun toString(): String = if (isInitialized()) value.toString() else "Lazy value not initialized yet."

private fun writeReplace(): Any = InitializedLazyImpl(value)

}

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值