[英]Setting variable in one thread by another
為什么在另一個線程調用的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
是獲得該保證的一種方法。
松散地說,您必須詢問是否需要可見性,否則運行時可以自由跳過它以進行優化。 例如,它可能使用寄存器來存儲主線程的pool
值,而不是在堆中更新對象中的字段。 您的代碼沒有表明其他線程應該能夠區分出差異,因此允許運行時執行優化。
該行為是有道理的:您的main()
中沒有sleep()
-因此它能夠快速連續執行五次減量。 然后在1000毫秒后f()
之后每隔一秒f()
調用f()
以將池設置為5。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.