gpt4 book ai didi

multithreading - Kotlin 局部变量线程安全

转载 作者:行者123 更新时间:2023-12-04 06:49:01 26 4
gpt4 key购买 nike

所以我正在编写一个单元测试来测试一些多线程,我想知道这段代码是否能保证按我的预期工作。

fun testNumbers() {
var firstNumber: Int? = null
var secondNumber: Int? = null
val startLatch = CountDownLatch(2)
val exec = Executors.newFixedThreadPool(2)

exec.submit({
startLatch.countDown()
startLatch.await()
firstNumber = StuffDoer.makeNumber()
})
exec.submit({
startLatch.countDown()
startLatch.await()
secondNumber = StuffDoer().makeNumber()
})
while (firstNumber == null || secondNumber == null) {
Thread.sleep(1)
}
}

具体来说,这个方法能保证完成吗? firstNumbersecondNumber 不是 volatile 那么这是否意味着运行测试的线程可能永远不会看到 exec 线程中这些值中设置的结果?您不能将 volatile 应用于局部变量,因此实际上对我来说,如果可能需要,您不能将函数局部变量设为 volatile 是没有意义的。

(我添加了 Java 作为标签,因为大概基本问题在 Java 中是相同的。)

最佳答案

使用 Kotlin 1.1 RC 编译器编译时,代码中的局部变量存储在 ObjectRef 中,然后在 lambdas 中使用。

您可以使用 Kotlin bytecode viewer 检查一段代码被编译成什么。

ObjectRef 将引用存储在非 volatile 字段 中,因此确实无法保证程序完成。

早期版本的 Kotlin 曾经在 volatile 类中有一个 Ref 字段,但这是 Kotlin 1.1 中的 has eventually been changed 的一个未记录的实现细节(即不可依赖的东西)。有关非 volatile 捕获变量背后的动机,请参阅 this thread

正如 the issue 描述中所说,

If a user is capturing a variable and handing it to other threads to work with, then it is a requirement of whatever concurrency control mechanism they are using to establish the corresponding happens-before edges between reads and writes to the captured variables. All regular concurrency mechanisms like starting/joining threads, creating futures, etc do so.



为了使您的示例程序正确同步,在从 .get() 返回的两个 Future 实例上调用 exec.submit { } 就足够了,因为 Future 提供了happens-before 保证:

Actions taken by the asynchronous computation represented by a Future happen-before actions subsequent to the retrieval of the result via Future.get() in another thread.


val f1 = exec.submit { /* ... */ }
val f2 = exec.submit { /* ... */ }

f1.get()
f2.get()

// Both assignments made in the submitted tasks are visible now
assert(firstNumber != null)
assert(secondNumber != null)

关于multithreading - Kotlin 局部变量线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42479009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com