美文网首页
kotlin 单例模式的多种实现

kotlin 单例模式的多种实现

作者: 100个大西瓜 | 来源:发表于2022-09-21 00:32 被阅读0次

线程不安全的实现方式

package com.sheby.hfdpkt.chap05.singleton

import kotlin.concurrent.thread

/**
 * 线程不安全的单例:传统方法
 */
class ThreadNotSafeSingleton private constructor() {

    init {
        println("ThreadNotSafeSingleton")
    }

    companion object {

        private var singleton: ThreadNotSafeSingleton? = null
            get() {
                if (field == null) {
                    field = ThreadNotSafeSingleton()
                }
                return field
            }

        @JvmStatic
        fun getInstance(): ThreadNotSafeSingleton {
            return singleton!!
        }
    }

}

fun main() {
    thread {
        println("thread ${ThreadNotSafeSingleton.getInstance()}")
    }
    println("main ${ThreadNotSafeSingleton.getInstance()}")

}

《head first 设计模式》中对于单例有三种线程安全的实现方式

1.直接同步getInstance()方法,

肯定线程安全,但会有性能问题;

package com.sheby.hfdpkt.chap05.singleton

import kotlin.concurrent.thread

/**
 * 线程安全的单例
 * 使用锁
 */
class ThreadSafeSingleton private constructor() {

    init {
        println("ThreadSafeSingleton")
    }

    companion object {
        private var singleton: ThreadSafeSingleton? = null

        @JvmStatic
        @Synchronized
        fun getInstance(): ThreadSafeSingleton {
            if (singleton == null) {
                singleton = ThreadSafeSingleton()
            }
            return singleton!!
        }

    }
}

fun main() {
    thread {
        println("thread ${ThreadSafeSingleton.getInstance()}")
    }
    println("main ${ThreadSafeSingleton.getInstance()}")
}

2.在getInstance()中双重检查加锁,

只有单例未创建之前才会进入锁的代码块,减少不必要的同步次数,提高性能;

package com.sheby.hfdpkt.chap05.singleton

import kotlin.concurrent.thread

/**
 * 线程安全的单例
 * 使用双重检查加锁的方法:只适用于jdk5之后的
 */
class DoubleCheckSingleton private constructor() {

    init {
        println("DoubleCheckSingleton")
    }

    companion object {
        @Volatile
        private var sSingleton: DoubleCheckSingleton? = null
//            get() {
//                if (field == null) {
//                    synchronized(DoubleCheckSingleton::class) {
//                        if (field == null) {
//                            field = DoubleCheckSingleton()
//                        }
//                    }
//                }
//                return field
//            }

        @JvmStatic
        fun getInstance(): DoubleCheckSingleton {
            if (sSingleton == null) {
                synchronized(DoubleCheckSingleton::class) {
                    if (sSingleton == null) {
                        sSingleton = DoubleCheckSingleton()
                    }
                }
            }
            return sSingleton!!
        }
    }
}


fun main() {
    thread {
        println("thread ${DoubleCheckSingleton.getInstance()}")
    }
    println("main ${DoubleCheckSingleton.getInstance()}")

}

3.使用饿汉模式(急切实例化),

直接创建出该对象,但这样在没有使用到该对象之前,提前创建会多多少少浪费资源;

package com.sheby.hfdpkt.chap05.singleton

import kotlin.concurrent.thread

/**
 * 饿汉模式的单例:线程安全
 */
class HungrySingleton private constructor() {
    init {
        println("HungrySingleton")
    }

    companion object {
        private var singleton = HungrySingleton()

        @JvmStatic
        fun getInstance(): HungrySingleton {
            return singleton
        }
    }

}


fun main() {
    // TODO: 理论上 要先打印 "HungrySingleton"再打印 "main--"的
    //  可能是kotlin 编译出来的多了个HungrySingletonKt.class,而这main函数在这个类里面
    println("main--")
    thread {
        println("thread ${HungrySingleton.getInstance()}")
    }
    println("main ${HungrySingleton.getInstance()}")

}

此外还有java的静态内部类实现的单例,kotlin版本

参考来源

package com.sheby.hfdpkt.chap05.singleton

import kotlin.concurrent.thread

/**
 *相当于JAVA的静态内部类单例
 * 参考自
 * https://blog.csdn.net/qq_40987010/article/details/122499694
 */
class InnerSingleton private constructor() {
    init {
        println("InnerSingleton")
    }

    private object InnerHolder {
        val singleton = InnerSingleton()
    }

    companion object {
        @JvmStatic
        fun getInstance(): InnerSingleton {
            return InnerHolder.singleton
        }
    }

}

fun main() {
    thread {
        println("thread ${InnerSingleton.getInstance()}")
    }
    println("main ${InnerSingleton.getInstance()}")
}

最后当然少不了kotlin自带的object关键字 的单例模式

如果构造方法没有参数,使用这种方式是最简单的

package com.sheby.hfdpkt.chap05.singleton

import kotlin.concurrent.thread

object KotlinSingleton {
    init {
        println("create KotlinSingleton ${Thread.currentThread().name}}")
        Thread.sleep(200)
    }
}

fun main() {
    thread {
        println("thread $KotlinSingleton")
    }
    println("main $KotlinSingleton")
}

github源码

相关文章

网友评论

      本文标题:kotlin 单例模式的多种实现

      本文链接:https://www.haomeiwen.com/subject/pztyortx.html