Java 为什么可以';t while(flag){}end

Java 为什么可以';t while(flag){}end,java,kotlin,Java,Kotlin,代码如下: fun main(args: Array<String>) { var flag = true Thread { Thread.sleep(2000) println("time over") flag = false }.start() while (flag) { Thread.sleep(100) } println("finish") } 节目结束了 如果更改为: fun main(args: Array<String>

代码如下:

fun main(args: Array<String>) {
var flag = true
Thread {
    Thread.sleep(2000)
    println("time over")
    flag = false
}.start()
while (flag) {
    Thread.sleep(100)
}
println("finish")
}
节目结束了

如果更改为:

fun main(args: Array<String>) {
var flag = true
Thread {
    Thread.sleep(2000)
    println("time over")
    flag = false
}.start()
while (flag) {
   //Do nothing
}
println("finish")
}
fun main(args:Array){
var flag=true
线{
《睡眠》(2000年)
println(“时间结束”)
flag=false
}.start()
while(旗帜){
//无所事事
}
println(“完成”)
}

“finish”无法打印,程序被卡住。为什么会这样?

因为您将获得标志的缓存版本。看看volatile关键字


基本上,这里您正在更新一个线程中的标志,但另一个线程仍然看到标志的缓存版本。

问题是第一个线程需要时间将标志设置为false,但在线程完成之前执行循环时,这意味着您的标志仍然为true,因此它永远不会变为false。 我们需要在线程完成后设置流,然后检查使用线程睡眠的while条件

var flag = true
Thread {
    Thread.sleep(2000)
    println("time over")
    flag = false
}.start()
Thread.sleep(3000)
while (flag) {

}

println("finish")

当变量标志未声明为volatile时,编译器有时(取决于使用的)会将while循环代码优化为以下内容:

if (condition) {
    while (true) {
        // Do nothing
    }
}

有关更多信息,请参阅。这是一个。

啊,你为了同样的答案比我快了2秒:)非常感谢你让我知道Volatile的用法o为什么OP的第二个案例中“超时”也没有打印?println(“超时”)正在打印,但在第二个案例中没有打印“完成”,将标志标记为“@Volatile var flag=true”非常感谢您让我知道volatile的用法
if (condition) {
    while (true) {
        // Do nothing
    }
}