1 kotlin
我们知道,全局变量的值可以随时被其他线程修改。但是为什么?.letkotlin 可以防止多线程中的 NPE 呢?例如:
var demo : Demo? = null
demo = Demo()
Thread{
demo?.let {
while (true){
it.run()
Thread.sleep(300)
}
}
}.start()
Thread.sleep(3000)
demo = null
Run Code Online (Sandbox Code Playgroud)
上面的程序中,虽然主线程将变量设置demo为null,但子线程仍能正常执行。
那么,为什么“let”构造中的“it”不能受到其他线程的影响呢?它是对象“演示”的深层副本吗?
那么,为什么“let”构造中的“it”不能被其他线程影响呢?
.let { }确实没有什么神奇的。这是一个非常简单的功能。当您编写 时demo?.let { println(it) },代码实际上相当于:
val it = demo
if (it != null) {
println(it)
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,创建了一个新变量并将其值设置为demo。因此,如果其他线程修改demo,it不受影响。
这是对象“演示”的深层副本?
它实际上不是深层复制:如果线程改变了实例的属性Demo,则访问该实例*的任何代码都可以看到它们,甚至通过变量也是如此it。
但是,您不需要深复制此代码即可正常工作。demo是一个引用变量,最初指向Demo()代码开头创建的实例。
当我们这样做时val it = demo(从相当于 的代码?.let),我们将变量的当前值复制demo到 中it,并且该值是对该实例的引用Demo。我们说it“指向”与 相同的Demo实例demo。
当另一个线程设置demo为时null,它不会更改Demo实例中的任何内容。其效果是,现在demo不再指向初始Demo实例。但it还是指出了这一点。
(*虽然这里有一些微妙之处,比如先发生关系、易失变量等,但我们不要让事情复杂化)
| 归档时间: |
|
| 查看次数: |
67 次 |
| 最近记录: |