【问题标题】:Kotlin delegate property by lazy that is thread local惰性的 Kotlin 委托属性是线程本地的
【发布时间】:2017-08-30 22:39:57
【问题描述】:

有没有一种简单的方法来获取委托属性by lazy 的每个线程计算的值,例如ThreadLocal

LazyThreadSafetyMode 控制并发初始化,.NONE 通过允许多个线程接收不同的值来接近所需的功能,但后续初始化调用引用相同的对象,无论线程如何都返回相同的奇异值,某些情况下返回null

无论是并发初始化还是后期初始化,该属性都会为每个线程缓存一个唯一值。

【问题讨论】:

    标签: properties delegates kotlin lazy-evaluation thread-local


    【解决方案1】:

    Kotlin delegates 很容易通过您自己的实现进行扩展。

    • 您可以让您的委托维护一个 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()
      }
      
    • 或者用ThreadLocal&lt;Lazy&lt;T&gt;&gt;为每个线程维护一个Lazy&lt;T&gt;,这样你的委托就可以自己实现Lazy&lt;T&gt;

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

    这是一个创建委托实例的便捷函数:

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

    然后将一个属性委托给threadLocalLazy { ... }。使用示例:

    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
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-02
      • 2023-04-02
      • 1970-01-01
      • 2017-08-01
      • 2017-11-08
      • 1970-01-01
      • 2017-01-18
      • 2020-07-04
      相关资源
      最近更新 更多