java - Kotlin 中的线程同步是如何工作的?

标签 java kotlin synchronization kotlin-coroutines kotlin-android-extensions

我一直在尝试 Kotlin 同步,但我从文档中不了解锁定机制如何在公共(public)资源上的线程同步上起作用,因此试图编写这段代码,这进一步使我的理解复杂化。

fun main() {
    val myList = mutableListOf(1)

    thread {
        myList.forEach {
            while (true) {
                println("T1 : $it")
            }
        }
    }

    thread {
        synchronized(myList) {
            while (true) {
                myList[0] = 9999
                println("**********\n**********\n**********\n")
            }
        }
    }
}
myList是有问题的公共(public)资源。

第一个线程是一个简单的读取操作,我打算将资源保持在读取模式下使用。第二个是另一个请求锁以修改公共(public)资源的线程。

虽然第一个线程不包含任何同步,但我希望它能够在内部处理这个问题,以便一段时间像 map 这样的函数或 forEach正在处理资源,另一个线程不应该能够锁定它,否则被迭代的元素可能会在 map/forEach正在进行中(即使该操作可能会暂停一段时间,而另一个线程对其进行了锁定)。

相反,我看到的输出显示两个线程都在并行执行。它们都分别打印列表中的第一个元素和星星。但是在第二个线程中,即使正在打印星星,myList[0]永远不会设置为 9999,因为第一个线程继续打印 1。

最佳答案

第二个线程没有改变第一个列表元素的值,如 ==意味着比较,而不是分配。您需要使用 = tio 更改值,例如myList[0] = 9999 .但是,在您的代码中,不能保证第二个线程的更改将在第一个线程中可见,因为线程一个未在 myList 上同步.

如果您的目标是 JVM,您应该阅读有关 JVM 内存模型的信息,例如什么是 @Volatile .您当前的方法不能保证第一个线程会看到第二个线程的更改。您可以将代码简化为 splinter 例子:

var counter = 1

fun main() {
    thread {
        while (counter++ < 1000) {
            println("T1: $counter")
        }
    }
    thread {
        while (counter++ < 1000) {
            println("T2: $counter")
        }
    }
}

可以打印奇怪的结果,例如:

T2: 999
T1: 983
T2: 1000

这可以通过几种方式解决,例如通过使用同步。

关于java - Kotlin 中的线程同步是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61828169/

相关文章:

generics - Kotlin 强制可空泛型类型转换为同一泛型类型的不可空泛型?

Java程序写入后无法使用文件写入

java - 如何将带分隔符的平面文件解析为 POJO

kotlin - 使用 Kotlin JS 'fun <T> parse(text: String): T` 解析 JSON?

java - 在System.setProperty中加载Jar中的JKS

Kotlin Excessed 通过引用创建实体

python - P4Python 使用参数 -I 指标

字符串作为id的java同步

java - 如何在其他窗口之上生成一个独立的 JFileChooser 对话框?

java - 在多个项目中使用同一个 Hibernate 管理的数据库会导致问题吗?