Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2019-07-12:Kotlin中实现单例的几种常见方式? #96

Open
Moosphan opened this issue Jul 12, 2019 · 12 comments
Open

2019-07-12:Kotlin中实现单例的几种常见方式? #96

Moosphan opened this issue Jul 12, 2019 · 12 comments
Labels

Comments

@Moosphan
Copy link
Owner

No description provided.

@Moosphan Moosphan changed the title 2019-07-12:Kotlin中如何快速实现单例模式? 2019-07-12:Kotlin中实现单例的几种常见方式? Jul 12, 2019
@DaveBoy
Copy link

DaveBoy commented Jul 12, 2019

by lazy 加上同步关键字sy

@yangfanggang
Copy link

不会kotlin
打卡
告辞

@Moosphan
Copy link
Owner Author

  • 饿汉式:
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
Copy link

object

@574085757
Copy link

574085757 commented Jul 15, 2019

companion object {
val instance: SyncData by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {SyncData() }
}

@liyuxuanAdoreLi
Copy link

  • 饿汉式:
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
Copy link

weikano commented Sep 2, 2019

不会用枚举?

:octocat: From gitme iOS

@xiaoyunfei
Copy link

  • 饿汉式:
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
Copy link

skymxc commented Jan 6, 2021

  • 饿汉式:
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
Copy link

饿汉式

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
Copy link

楼上所有的懒汉式 对象变量都声明为私有的了,私有变量外界如何获取?

@huanzhiyazi
Copy link

楼上所有的懒汉式 对象变量都声明为私有的了,私有变量外界如何获取?

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() {}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests