【发布时间】:2019-08-24 06:30:49
【问题描述】:
我正在阅读教程 https://www.youtube.com/watch?v=SC2jXxOPe5E 以了解 volatile 变量的工作原理并遇到了一个奇怪的行为。
对于下面的代码sn -p
public class VolatileDemo {
static boolean running = false;
public static void main(String a[]) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (!running) {
}
System.out.print("Started");
while (running) {
}
System.out.print("Stopped");
}
});
t.start();
Thread.sleep(1000);
running = true;
System.out.print("Starting ");
Thread.sleep(1000);
running = false;
System.out.print("Stopping");
}
}
输出为:Starting Stopping(通过视频可以理解)
但是对于下面的代码sn-p
public class VolatileDemo {
static boolean running = false;
public static void main(String a[]) throws InterruptedException {
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while (!running) {
System.out.print("Flag " + running);
}
System.out.print(" Started");
while (running) {
System.out.print(" Flag " + running);
}
System.out.print(" Stopped");
}
});
t.start();
Thread.sleep(1000);
running = true;
System.out.print(" Starting");
Thread.sleep(1000);
running = false;
System.out.print(" Stopping");
}
}
输出为 Flag: false Starting Started Flag: true Stopping Stopped(忽略输出)
我关心的是为什么线程能够在案例 2 中读取 'running' 的更新值?
编辑:这两个sn-ps的区别是在后面的情况下添加了下面的语句
System.out.print("Flag " + running);
【问题讨论】:
-
您的代码 sn-ps 似乎相同。你能强调一下不同之处吗?
-
你的逻辑错了。使变量 volatile 允许带来内存可见性保证,并使代码线程安全。这并不意味着不使用 volatile 可以保证内存不可见。就像:过马路前看两边,确保你不会被车撞到。这并不意味着如果您在过马路前不看一眼,就一定会被车撞到。这样做是不安全的,但不能保证你会发生事故。
-
@JBNizet 很好的比喻
标签: java multithreading jvm thread-safety volatile