2019-07-12:Kotlin中实现单例的几种常见方式?
Moosphan opened this issue · 13 comments
Moosphan commented
2019-07-12:Kotlin中实现单例的几种常见方式?
DaveBoy commented
by lazy 加上同步关键字sy
yangfanggang commented
不会kotlin
打卡
告辞
Moosphan commented
- 饿汉式:
object StateManagementHelper {
fun init() {
//do some initialization works
}
}
- 懒汉式:
class StateManagementHelper private constructor(){
companion object {
private var instance: StateManagementHelper? = null
@Synchronized get() {
if (field == null)
field = StateManagementHelper()
return field
}
}
fun init() {
//do some initialization works
}
}
- 双重检测:
class StateManagementHelper private constructor(){
companion object {
val instance: StateManagementHelper
by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { StateManagementHelper() }
}
fun init() {
//do some initialization works
}
}
- 静态内部类:
class StateManagementHelper private constructor(){
companion object {
val INSTANCE = StateHelperHolder.holder
}
private object StateHelperHolder {
val holder = StateManagementHelper()
}
fun init() {
//do some initialization works
}
}
18361237136 commented
object
574085757 commented
companion object {
val instance: SyncData by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {SyncData() }
}
liyuxuanAdoreLi commented
- 饿汉式:
object StateManagementHelper { fun init() { //do some initialization works } }
- 懒汉式:
class StateManagementHelper private constructor(){ companion object { private var instance: StateManagementHelper? = null @Synchronized get() { if (field == null) field = StateManagementHelper() return field } } fun init() { //do some initialization works } }
- 双重检测:
class StateManagementHelper private constructor(){ companion object { val instance: StateManagementHelper by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { StateManagementHelper() } } fun init() { //do some initialization works } }
- 静态内部类:
class StateManagementHelper private constructor(){ companion object { val INSTANCE = StateHelperHolder.holder } private object StateHelperHolder { val holder = StateManagementHelper() } fun init() { //do some initialization works } }
这个回答比较全,
关于双重校验,kotlin用了委托机制的延迟属性: lazy(「lambda表达式」),这一点真的爽歪歪
其他的与java没有什么区别
weikano commented
不会用枚举?
xiaoyunfei commented
- 饿汉式:
object StateManagementHelper { fun init() { //do some initialization works } }
- 懒汉式:
class StateManagementHelper private constructor(){ companion object { private var instance: StateManagementHelper? = null @Synchronized get() { if (field == null) field = StateManagementHelper() return field } } fun init() { //do some initialization works } }
- 双重检测:
class StateManagementHelper private constructor(){ companion object { val instance: StateManagementHelper by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { StateManagementHelper() } } fun init() { //do some initialization works } }
- 静态内部类:
class StateManagementHelper private constructor(){ companion object { val INSTANCE = StateHelperHolder.holder } private object StateHelperHolder { val holder = StateManagementHelper() } fun init() { //do some initialization works } }
双重检查锁,没有必要写mode = LazyThreadSafetyMode.SYNCHRONIZED,因为这是默认的方式,当然了,写上也不会有错
skymxc commented
- 饿汉式:
object StateManagementHelper { fun init() { //do some initialization works } }
- 懒汉式:
class StateManagementHelper private constructor(){ companion object { private var instance: StateManagementHelper? = null @Synchronized get() { if (field == null) field = StateManagementHelper() return field } } fun init() { //do some initialization works } }
- 双重检测:
class StateManagementHelper private constructor(){ companion object { val instance: StateManagementHelper by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { StateManagementHelper() } } fun init() { //do some initialization works } }
- 静态内部类:
class StateManagementHelper private constructor(){ companion object { val INSTANCE = StateHelperHolder.holder } private object StateHelperHolder { val holder = StateManagementHelper() } fun init() { //do some initialization works } }
我有一个疑问,在懒汉式的写法里,在半生对象里的访问修饰符是 private 外面能访问到吗?
class StateManagementHelper private constructor(){
companion object {
//这里是私有的啊????
private var instance: StateManagementHelper? = null
@Synchronized get() {
if (field == null)
field = StateManagementHelper()
return field
}
}
fun init() {
//do some initialization works
}
}
Quyunshuo commented
饿汉式
object Singleton
线程安全的懒汉式
class Singleton private constructor() {
companion object {
private var instance: Singleton? = null
get() {
if (field == null) field = Singleton()
return field
}
@Synchronized
fun instance(): Singleton {
return instance!!
}
}
}
双重校验锁式
/**
* 双重校验锁式
* Lazy是接受一个 lambda 并返回一个 Lazy 实例的函数,返回的实例可以作为实现延迟属性的委托
* 第一次调用 get() 会执行已传递给 lazy() 的 lambda 表达式并记录结果,后续调用 get() 只是返回记录的结果
* Lazy默认的线程模式就是 LazyThreadSafetyMode.SYNCHRONIZED 内部默认双重校验锁
* # Lazy内部实现
* ```
* public fun <T> lazy(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =
* when (mode) {
* LazyThreadSafetyMode.SYNCHRONIZED -> SynchronizedLazyImpl(initializer)
* LazyThreadSafetyMode.PUBLICATION -> SafePublicationLazyImpl(initializer)
* LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
* }
* ```
* ### Lazy接口
* ```
* public interface Lazy<out T> {
* //当前实例化对象,一旦实例化后,该对象不会再改变
* public val value: T
* //返回true表示,已经延迟实例化过了,false 表示,没有被实例化,
* //一旦方法返回true,该方法会一直返回true,且不会再继续实例化
* public fun isInitialized(): Boolean
* }
* ```
* ### SynchronizedLazyImpl
* ```
* private class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>, Serializable {
* private var initializer: (() -> T)? = initializer
* @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,用于下次判断时,直接返回高级函数的返回值
* _value = typedValue
* initializer = null
* typedValue
* }
* }
* }
* //省略部分代码
* }
* ```
*/
class Singleton private constructor() {
companion object {
val instance by lazy { Singleton() }
}
}
静态内部类式
class Singleton private constructor() {
companion object {
val instance = SingletonHolder.holder
}
private object SingletonHolder {
val holder = Singleton()
}
}
枚举式
enum class Singleton {
INSTANCE;
}
Quyunshuo commented
楼上所有的懒汉式 对象变量都声明为私有的了,私有变量外界如何获取?
huanzhiyazi commented
楼上所有的懒汉式 对象变量都声明为私有的了,私有变量外界如何获取?
class Singleton private constructor() {
companion object {
private var INSTANCE: Singleton? = null
get() {
if (field == null) field = Singleton()
return field
}
@Synchronized fun getInstance() = INSTANCE!!
}
fun foo() {}
}
staccar commented
到此一游