- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码:
public static boolean turn = true;
public static void main(String[] args) {
Runnable r1 = new Runnable() {
public void run() {
while (true) {
while (turn) {
System.out.print("a");
turn = false;
}
}
}
};
Runnable r2 = new Runnable() {
public void run() {
while (true) {
while (!turn) {
System.out.print("b");
turn = true;
}
}
}
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
在类里面,我们学习了使用非同步代码时可能出现的“可见性”问题。据我所知,为了节省时间,编译器将决定抓取 turn
到 CPU 中的缓存进行循环,这意味着线程不会知道是否 turn
值在 RAM 中被更改,因为他没有检查它。
据我了解,我希望代码像这样运行:
T1 将看到 turn 为 true -> 进入循环并打印 -> 将 turn 变为 false -> 卡住
T2 会认为转弯没有改变 -> 会卡住
我希望如果 T1 在 T2 之前开始:只会打印 'a' 并且两个线程将在无限循环中运行而不打印任何其他内容
但是,当我运行代码时,有时我会在两个线程都卡住之前收到一些“ababa...”。
我错过了什么?
编辑:
下面的代码符合我的预期:线程将在无限循环中运行:
public class Test extends Thread {
boolean keepRunning = true;
public void run() {
long count = 0;
while (keepRunning) {
count++;
}
System.out.println("Thread terminated." + count);
}
public static void main(String[] args) throws InterruptedException {
Test t = new Test();
t.start();
Thread.sleep(1000);
t.keepRunning = false;
System.out.println("keepRunning set to false.");
}
它们之间有什么不同?
最佳答案
When I run the code, sometimes I get a few "ababa...." before both threads will stuck.
我怀疑发生的事情是当代码被 JIT 编译时行为发生了变化。在 JIT 编译之前,写入是可见的,因为解释器正在执行直写。在 JIT 编译之后,缓存刷新或读取已被优化掉......因为内存模型允许这样做。
What am I missing ?
您缺少的是您希望未指定的行为 保持一致。它不一定是。毕竟,它是未指定的! (这是真的,即使我上面提出的解释是不正确的。)
关于java - 意外的线程行为。能见度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42176913/
我有以下代码: public static boolean turn = true; public static void main(String[] args) { Runnable r1
我是一名优秀的程序员,十分优秀!