【发布时间】:2020-02-28 13:45:58
【问题描述】:
我正在使用 Java 中的 volatile 关键字,并且我有这段代码试图显示一个线程不会看到另一个线程引入的更改,除非我们将数据声明为 volatile。我期待下面的代码永远不会终止,因为我没有将共享数据声明为易失性。知道为什么这段代码实际上会终止吗?
public class VolatileTest {
public static void main(String[] args) throws InterruptedException {
var holder = new Holder();
new Thread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) { }
for(int i = 0; i<100000; i++) {
holder.counter++;
}
}).start();
var t = new Thread(() -> {
while(holder.counter < 10000) {
System.out.println("Jestem w pętli");
try {
Thread.sleep(400);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
t.join();
}
static class Holder {
int counter = 0;
}
}
【问题讨论】:
-
你在哪里使用
volatile关键字?顺便说一句:永远不要写catch (InterruptedException e) { }异常应该被处理,至少记录 -
允许线程缓存非易失变量的值。这并不能保证他们不会看到变化。
-
这个答案解释了为什么你的代码在没有
volatile关键字 stackoverflow.com/a/30956634/5862990 的情况下“有效” -
这就是为什么测试多线程程序的正确性是一个难题。 Java 语言规范保证如果您遵守某些规则,您的程序将以某种方式运行。但是,它确实不保证如果您违反规则,您的程序将出现异常行为。最坏的情况是你测试了一些软件,它通过了你的所有测试,你把它寄给了一个重要的客户,然后在六个月后当他们升级他们的操作系统时,**** 击中了粉丝。它发生了。不要问我是怎么知道的!
标签: java multithreading volatile