为什么另一个线程调用的f()
方法中的pool
没有设置为5?
public class Main {
private static int pool = 5;
public static void main(String... arg) {
Th t = new Th();
Thread thread = new Thread(t);
thread.start();
while (true) {
if (pool >= 0)
System.out.println(pool--);
}
}
static void f() {
pool = 5;
System.out.println("main.Main.f:pool=" + pool);
}
}
class Th implements Runnable {
@Override
public void run() {
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Main.f();
}
}
}
输出:
5
4
3
2
1
0
main.Main.f:pool=5
main.Main.f:pool=5
main.Main.f:pool=5
main.Main.f:pool=5
我可以修复它,将pool
声明为 volatile
,但我不明白为什么它可以工作8(
最佳答案
一个线程写入的值并不总是能被另一个线程读取。为了保证可见性,需要有一个“内存屏障”,将字段声明为 volatile
是获得该保证的一种方法。
粗略地说,如果需要的话,您必须请求可见性,否则运行时可以作为优化而跳过它。例如,它可能使用寄存器来存储主线程的池值,而不是更新堆中对象的字段。您的代码并不表明其他线程应该能够区分差异,因此允许运行时执行优化。
关于java - 由另一个线程在一个线程中设置变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37283620/