java 变量的线程可见性_Java多线程——变量可见性
可見性是一種復雜的屬性,因為可見性中的錯誤總是會違背我們的直覺。在單線程環境中,如果向某個變量先寫入值,然后在沒有其他寫入操作的情況下讀取這個變量,那么總能得到相同的值。這看起來很自然。 然而,當讀操作和寫操作在不同的線程中執行時,情況卻并非如此。
public class NoVisiaility {
private static boolean ready;
private static int number;
private static class ReaderThread extends Thread {
public void run() {
while (!ready)
Thread.yield();
System.out.println(number);
}
}
/**
* @param args
*/
public static void main(String[] args) {
new ReaderThread().start();
number = 42;
ready = true;
}
}
在上面程序中,主線程和讀線程都訪問共享變量ready和number。主線程啟動讀線程,然后將number設為42,并將ready設為true。讀線程一直循環直到發現ready的值變為true,然后輸出number的值。雖然NoVisiaility看起來會輸出42,但事實上很可能輸出0,或根本無法終止。這是因為在代碼中沒有使用足夠的同步機制,因此無法保證主線程寫入的ready值和number值對于讀線程來說是可見的。
NoVisiaility可能會持續循環下去,因為讀線程可能永遠都看不到ready的值。一種更奇怪的現象時,NoVisiaility可能會輸出0,因為讀線程可能看到了寫入ready的值,但卻沒有看到之后寫入number的值,這種現象被稱為“重排序(Reorderiing)”。只要在某個線程中無法檢測到重排序情況(即使在其他線程中可以很明顯地看到該線程中的重排序),那么就無法確保線程中的操作將按照程序中指定的順序來執行。當主線程手寫如number,然后在沒有同步的情況下寫入ready,那么讀線程看到的順序可能與寫入的順序完全相反。 ? ? ? ? ?在沒有同步的情況下,編譯器、處理器以及運行時等都可能對操作的執行順序進行一些意想不到調整。在缺乏足夠同步的多線程程序中,要想對內存操作的執行順序進行判斷,幾乎無法得到正確的結論。
一種簡單的方法能夠避免這些復雜的問題:只要有數據在多個線程之間共享,就使用正確的同步。
總結
以上是生活随笔為你收集整理的java 变量的线程可见性_Java多线程——变量可见性的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求一个成语个性签名!
- 下一篇: “水边闲坐一绳床”上一句是什么