Lazy: Use UNINITIALIZED_VALUE instead of null to indicate that value was not initialized. Remove escape and unescape methods.

This commit is contained in:
Ilya Gorbunov
2015-06-15 22:57:41 +03:00
parent 59ff9dc3cf
commit bfdb200cc7
2 changed files with 34 additions and 32 deletions
+17 -26
View File
@@ -38,45 +38,36 @@ public enum class LazyThreadSafetyMode {
}
private object NULL_VALUE {}
private object UNINITIALIZED_VALUE
private fun escape(value: Any?): Any {
return value ?: NULL_VALUE
}
private fun unescape(value: Any?): Any? {
return if (value === NULL_VALUE) null else value
}
private class LazyImpl<out T>(initializer: () -> T, private val lockObj: Any) : Lazy<T> {
private class LazyImpl<out T>(initializer: () -> T) : Lazy<T> {
private var initializer: (() -> T)? = initializer
private volatile var _value: Any? = null
private volatile var _value: Any? = UNINITIALIZED_VALUE
public override val value: T
get() {
val _v1 = _value
if (_v1 != null) {
return unescape(_v1) as T
if (_v1 !== UNINITIALIZED_VALUE) {
return _v1 as T
}
return synchronized(lockObj) {
return synchronized(this) {
val _v2 = _value
if (_v2 != null) {
unescape(_v2) as T
if (_v2 !== UNINITIALIZED_VALUE) {
_v2 as T
}
else {
val typedValue = initializer!!()
_value = escape(typedValue)
_value = typedValue
initializer = null
typedValue
}
}
}
override val valueCreated: Boolean = _value == null
override val valueCreated: Boolean = _value !== UNINITIALIZED_VALUE
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not created yet."
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not initialized yet."
}
@@ -84,18 +75,18 @@ private class UnsafeLazyImpl<out T>(initializer: () -> T) : Lazy<T> {
private var initializer: (() -> T)? = initializer
private var _value: Any? = null
private var _value: Any? = UNINITIALIZED_VALUE
override val value: T
get() {
if (_value == null) {
_value = escape(initializer!!())
if (_value === UNINITIALIZED_VALUE) {
_value = initializer!!()
initializer == null
}
return unescape(_value) as T
return _value as T
}
override val valueCreated: Boolean = _value == null
override val valueCreated: Boolean = _value !== UNINITIALIZED_VALUE
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not created yet."
override fun toString(): String = if (valueCreated) value.toString() else "Lazy value not initialized yet."
}
+17 -6
View File
@@ -1,14 +1,25 @@
package kotlin
/** Initializes a new instance of the [Lazy] that uses the specified initialization function [initializer]
* and the default thread-safety [LazyThreadSafetyMode.SYNCHRONIZED]. */
public fun lazy<T>(initializer: () -> T): Lazy<T> = LazyImpl(initializer, Any())
/**
* Initializes a new instance of the [Lazy] that uses the specified initialization function [initializer]
* and the default thread-safety mode [LazyThreadSafetyMode.SYNCHRONIZED].
*
* Note that the returned instance uses itself to synchronize on. Do not synchronize from external code on
* the returned instance as it may cause accidental deadlock. Also this behavior can be changed in the future.
*/
public fun lazy<T>(initializer: () -> T): Lazy<T> = LazyImpl(initializer)
/** Initializes a new instance of the [Lazy] that uses the specified initialization function [initializer]
* and thread-safety [mode]. */
/**
* Initializes a new instance of the [Lazy] that uses the specified initialization function [initializer]
* and thread-safety [mode].
*
* Note that when the [LazyThreadSafetyMode.SYNCHRONIZED] mode is specified the returned instance uses itself
* to synchronize on. Do not synchronize from external code on the returned instance as it may cause accidental deadlock.
* Also this behavior can be changed in the future.
*/
public fun lazy<T>(mode: LazyThreadSafetyMode, initializer: () -> T): Lazy<T> =
when (mode) {
LazyThreadSafetyMode.SYNCHRONIZED -> LazyImpl(initializer, Any())
LazyThreadSafetyMode.SYNCHRONIZED -> LazyImpl(initializer)
LazyThreadSafetyMode.NONE -> UnsafeLazyImpl(initializer)
}