IR: make lazyVar synchronized
This commit is contained in:
@@ -8,22 +8,30 @@ package org.jetbrains.kotlin.ir.declarations.lazy
|
|||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
import kotlin.reflect.KProperty
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
fun <T> lazyVar(initializer: () -> T): ReadWriteProperty<Any?, T> = UnsafeLazyVar(initializer)
|
fun <T> lazyVar(initializer: () -> T): ReadWriteProperty<Any?, T> = SynchronizedLazyVar(initializer)
|
||||||
|
|
||||||
private class UnsafeLazyVar<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> {
|
private class SynchronizedLazyVar<T>(initializer: () -> T) : ReadWriteProperty<Any?, T> {
|
||||||
|
@Volatile
|
||||||
private var isInitialized = false
|
private var isInitialized = false
|
||||||
|
|
||||||
private var initializer: (() -> T)? = initializer
|
private var initializer: (() -> T)? = initializer
|
||||||
|
|
||||||
|
@Volatile
|
||||||
private var _value: Any? = null
|
private var _value: Any? = null
|
||||||
|
|
||||||
private val value: T
|
private val value: T
|
||||||
get() {
|
get() {
|
||||||
if (!isInitialized) {
|
|
||||||
_value = initializer!!()
|
|
||||||
isInitialized = true
|
|
||||||
initializer = null
|
|
||||||
}
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return _value as T
|
if (isInitialized) return _value as T
|
||||||
|
synchronized(this) {
|
||||||
|
if (!isInitialized) {
|
||||||
|
_value = initializer!!()
|
||||||
|
isInitialized = true
|
||||||
|
initializer = null
|
||||||
|
}
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return _value as T
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = if (isInitialized) value.toString() else "Lazy value not initialized yet."
|
override fun toString(): String = if (isInitialized) value.toString() else "Lazy value not initialized yet."
|
||||||
@@ -31,7 +39,9 @@ private class UnsafeLazyVar<T>(initializer: () -> T) : ReadWriteProperty<Any?, T
|
|||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
|
override fun getValue(thisRef: Any?, property: KProperty<*>): T = value
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
this._value = value
|
synchronized(this) {
|
||||||
isInitialized = true
|
this._value = value
|
||||||
|
isInitialized = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user