Kotlin由线程局部的懒惰代表财产
有没有一种简单的方法by lazy
像ThreadLocal
这样每个线程计算出by lazy
值来获得委托属性?
LazyThreadSafetyMode
控制并发初始化, .NONE
通过允许多个线程接收不同的值而接近所需的功能,但后续的后期初始化调用引用相同的对象,不管线程返回相同的奇异值,有些情况返回null
。
无论并发初始化还是后期初始化,该属性都会为每个线程缓存一个唯一的值。
科特林代表很容易通过自己的实现来扩展。
-
你可以让你的委托维护一个
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<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() }
这里有一个方便的功能来创建委托的实例:
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 } } }