DPM*_*DPM 0 java multithreading
我有以下问题:为什么在这种情况下第二个线程看到第一个线程何时更改数字的值:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
我期望从第二个线程缓存数值,当第一个线程更改它时,第二个线程将"不知情",并且它将始终打印2!但实际上当第一个线程更改了数字变量时,第二个线程会看到此更改并开始打印100.为什么会这样?我知道第二个线程不会100%确定缓存变量,但在大多数情况下它会这样做.我遗漏的东西很重要.提前致谢.
根据Java内存模型,不能保证一个线程更改的值将从另一个线程可见.然而,它并没有反过来说:它可以是可见的.这取决于虚拟机和硬件的实现.如果今天在您的CPU上使用您的VM可见,并不意味着它将始终在每个硬件和每个虚拟机上都可见.你不能依靠这个.
如果您仍想查看效果,可以使用以下代码替换第二个线程代码:
new Thread(new Runnable() {
@Override
public void run() {
while (number < 100) {
}
System.out.println(number);
}
}).start();
Run Code Online (Sandbox Code Playgroud)
这会在HotSpot虚拟机上产生稳定的结果:您的程序永远不会结束(尽管volatile在number字段上添加关键字将使其在5秒内结束).当然你也不能依赖这个.