gpt4 book ai didi

Java并发

转载 作者:行者123 更新时间:2023-12-01 07:04:05 25 4
gpt4 key购买 nike

我有以下问题:为什么在这种情况下第二个线程会看到第一个线程更改 number 的值:

public static void main(String[] args) throws InterruptedException {

Temp t = new Temp();
t.go();
}

static class Temp {
int number = 2;

public void go() {

new Thread(new Runnable() {

@Override
public void run() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}

number = 100;
}
}).start();

new Thread(new Runnable() {

@Override
public void run() {
while (true) {
System.out.println(number);
}
}
}).start();
}
}

我期望从第二个线程缓存数值,当第一个线程更改它时,第二个线程将对此“不知情”,并且它将始终打印 2 !但实际上,当第一个线程更改数字变量时,第二个线程会看到此更改并开始打印 100。为什么会这样?我知道不能 100% 确定第二个线程会缓存该变量,但在大多数情况下它会这样做。我觉得我错过了一些重要的事情。提前致谢。

最佳答案

根据 Java 内存模型不能保证一个线程更改的值对于另一个线程是可见的。然而它并没有说相反的:它是可见的。这取决于虚拟机和您的硬件的实现。如果它现在在您的 CPU 和 VM 上可见,并不意味着它在每个硬件和每个虚拟机上始终可见。你不能依赖这个。

如果你还想看到效果,可以将第二个线程代码替换为以下代码:

new Thread(new Runnable() {

@Override
public void run() {
while (number < 100) {
}
System.out.println(number);
}
}).start();

这会在 HotSpot 虚拟机上产生稳定的结果:您的程序永远不会结束(尽管在 number 字段上添加 volatile 关键字将使程序在 5 秒内结束)。当然你也不能依赖这个。

关于Java并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31003142/

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