Lazy: changes and clarifications after code-review.

LazyThreadSafety.NONE is actually *NONE* now.
This commit is contained in:
Ilya Gorbunov
2015-09-25 19:13:12 +03:00
parent 74f39c2375
commit 1145cc0d1b
2 changed files with 10 additions and 4 deletions
+2 -1
View File
@@ -63,6 +63,7 @@ private object UNINITIALIZED_VALUE
internal class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>(), Serializable { internal class SynchronizedLazyImpl<out T>(initializer: () -> T, lock: Any? = null) : Lazy<T>(), Serializable {
private var initializer: (() -> T)? = initializer private var initializer: (() -> T)? = initializer
@Volatile private var _value: Any? = UNINITIALIZED_VALUE @Volatile private var _value: Any? = UNINITIALIZED_VALUE
// final field is required to enable safe publication of constructed instance
private val lock = lock ?: this private val lock = lock ?: this
override val value: T override val value: T
@@ -101,7 +102,7 @@ internal class UnsafeLazyImpl<out T>(initializer: () -> T) : Lazy<T>(), Serializ
get() { get() {
if (_value === UNINITIALIZED_VALUE) { if (_value === UNINITIALIZED_VALUE) {
_value = initializer!!() _value = initializer!!()
initializer == null initializer = null
} }
return _value as T return _value as T
} }
+8 -3
View File
@@ -51,14 +51,19 @@ public fun lazy<T>(lock: Any?, initializer: () -> T): Lazy<T> = SynchronizedLazy
private class SafePublicationLazyImpl<out T>(initializer: () -> T) : Lazy<T>(), Serializable { private class SafePublicationLazyImpl<out T>(initializer: () -> T) : Lazy<T>(), Serializable {
private var initializer: (() -> T)? = initializer private var initializer: (() -> T)? = initializer
@Volatile private var _value: Any? = UNINITIALIZED_VALUE @Volatile private var _value: Any? = UNINITIALIZED_VALUE
// this final field is required to enable safe publication of constructed instance
private val final: Any = UNINITIALIZED_VALUE private val final: Any = UNINITIALIZED_VALUE
override val value: T override val value: T
get() { get() {
if (_value === UNINITIALIZED_VALUE) { if (_value === UNINITIALIZED_VALUE) {
val newValue = initializer!!() val initializerValue = initializer
if (valueUpdater.compareAndSet(this, UNINITIALIZED_VALUE, newValue)) { // if we see null in initializer here, it means that the value is already set by another thread
initializer == null if (initializerValue != null) {
val newValue = initializerValue()
if (valueUpdater.compareAndSet(this, UNINITIALIZED_VALUE, newValue)) {
initializer = null
}
} }
} }
return _value as T return _value as T