Kotlin delegate 属性 by lazy 是线程本地的
Kotlin delegate property by lazy that is thread local
是否有一种简单的方法可以像 ThreadLocal
一样获取每个线程计算的委托 属性 by lazy
的值?
LazyThreadSafetyMode
控制并发初始化,.NONE
通过允许多个线程接收不同的值来接近所需的功能,但后续 post 初始化调用引用同一对象,无论线程如何,都返回相同的奇异值,在某些情况下返回 null
。
无论是并发初始化还是延迟初始化,属性 都会为每个线程缓存一个唯一值。
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<Lazy<T>>
为每个线程维护一个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
}
}
}
是否有一种简单的方法可以像 ThreadLocal
一样获取每个线程计算的委托 属性 by lazy
的值?
LazyThreadSafetyMode
控制并发初始化,.NONE
通过允许多个线程接收不同的值来接近所需的功能,但后续 post 初始化调用引用同一对象,无论线程如何,都返回相同的奇异值,在某些情况下返回 null
。
无论是并发初始化还是延迟初始化,属性 都会为每个线程缓存一个唯一值。
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<Lazy<T>>
为每个线程维护一个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
}
}
}