最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

multithreading - Can a @Volatile lateinit var be atomically initialized using a DCL pattern in Kotlin? - Stack Overflow

programmeradmin1浏览0评论

Consider the following DCL example written in Kotlin:

@Volatile
private var property: String? = null

private val lock = ReentrantLock()

fun singletonValue(): String {
    if (property == null) {
        lock.withLock {
            if (property == null) {
                property = "Hello World"
            }
        }
    }
    return property!!
}

It's pretty much the same as its Java counterpart discussed like two decades ago, when Java Memory Model was corrected with the transition from Java 1.4 to Java 5. Having said that, I'm perfectly sure the above code fragment will behave correctly when run on the JVM.

Now, let's use a lateinit var instead:

@Volatile
private lateinit var property: String

private val lock = ReentrantLock()

fun singletonValue(): String {
    if (!::property.isInitialized) {
        lock.withLock {
            if (!::property.isInitialized) {
                property = "Hello World"
            }
        }
    }
    return property
}

Is it semantically equivalent to the original example? Does it maintain the same atomicity and visibility guarantees?

Consider the following DCL example written in Kotlin:

@Volatile
private var property: String? = null

private val lock = ReentrantLock()

fun singletonValue(): String {
    if (property == null) {
        lock.withLock {
            if (property == null) {
                property = "Hello World"
            }
        }
    }
    return property!!
}

It's pretty much the same as its Java counterpart discussed like two decades ago, when Java Memory Model was corrected with the transition from Java 1.4 to Java 5. Having said that, I'm perfectly sure the above code fragment will behave correctly when run on the JVM.

Now, let's use a lateinit var instead:

@Volatile
private lateinit var property: String

private val lock = ReentrantLock()

fun singletonValue(): String {
    if (!::property.isInitialized) {
        lock.withLock {
            if (!::property.isInitialized) {
                property = "Hello World"
            }
        }
    }
    return property
}

Is it semantically equivalent to the original example? Does it maintain the same atomicity and visibility guarantees?

Share Improve this question asked Feb 7 at 17:40 BassBass 5,3182 gold badges40 silver badges92 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

These two code snippets compile to the almost same bytecode. lateinit properties are just compiled into regular Java fields, and isInitialized is basically a null check.

The only difference is the last return statement. An access to an uninitialised lateinit property will throw a UninitializedPropertyAccessException, whereas property!! will throw a NullPointerException when property is null. Of course, this difference is irrelevant to whether the same thread safety guarantees hold.

That said, there is no Kotlin/JVM specification yet, and the Kotlin/Core specification doesn't mention anything about concurrency. So strictly speaking, there is little guarantee about how your Kotlin code is going to be compiled into bytecode.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论