简体   繁体   English

Kotlin委托属性由lazy本地线程

[英]Kotlin delegate property by lazy that is thread local

Is there a simple way get a delegated property by lazy 's value computed per thread like ThreadLocal ? 是否有一种简单的方法可以by lazyThreadLocal这样的每个线程计算by lazy值来获取委托属性?

LazyThreadSafetyMode controls concurrent initialization, with .NONE coming close to the desired functionality by allowing multiple threads to receive different values, but has subsequent post initialization calls referencing the same object, returning the same singular value regardless of thread, with some cases returning null . LazyThreadSafetyMode控制并发初始化, .NONE接近所需的功能,允许多个线程接收不同的值,但后续的后初始化调用引用相同的对象,返回相同的奇异值而不管线程,有些情况下返回null

Regardless of concurrent initialization, or late initialization, the property would cache a unique value per thread. 无论是并发初始化还是后期初始化,该属性都会为每个线程缓存一个唯一值。

The Kotlin delegates are easy to extend with your own implementation. Kotlin代表很容易使用您自己的实现进行扩展。

  • You can make your delegate maintain a ThreadLocal<T> with initialValue calculated by the function that is passed: 您可以使您的委托维护一个ThreadLocal<T>其中initialValue由传递的函数计算:

     class ThreadLocalLazy<T>(val provider: () -> T) :ReadOnlyProperty<Any?, T> { private val threadLocal = object : ThreadLocal<T>() { override fun initialValue(): T = provider() } override fun getValue(thisRef: Any?, property: KProperty<*>): T = threadLocal.get() } 
  • Or maintain a Lazy<T> per thread with ThreadLocal<Lazy<T>> , so that your delegate can implement Lazy<T> by itself: 或维持一个Lazy<T>每个线程与ThreadLocal<Lazy<T>> ,让您的代理可以实现Lazy<T>本身:

     class ThreadLocalLazy<T>(val provider: () -> T) : Lazy<T> { private val threadLocal = object : ThreadLocal<Lazy<T>>() { override fun initialValue(): Lazy<T> = lazy(LazyThreadSafetyMode.NONE, provider) } override val value get() = threadLocal.get().value override fun isInitialized() = threadLocal.get().isInitialized() } 

Here's a convenience function to create instances of the delegate: 这是创建委托实例的便捷功能:

fun <T> threadLocalLazy(provider: () -> T) = ThreadLocalLazy(provider)

Then just delegate a property to threadLocalLazy { ... } . 然后只需将属性委托给threadLocalLazy { ... } Usage example: 用法示例:

class Example {
    val threadId by threadLocalLazy { Thread.currentThread().id }
}

fun main(args: Array<String>) {
    val example = Example()
    repeat(3) {
        thread {
            println(example.threadId) // should print three different numbers
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM