簡體   English   中英

java synchronized線程澄清

[英]java synchronized Thread clarification

這個程序的答案必須在5秒后完成“改變完成”,但我得到“改變完成”和“完成”。 我沒有getDone方法同步。 我有什么想法為線程完成處理。

public class Main {
    private static boolean done = false;
    private static int count;

    public static void main(String[] args)throws InterruptedException {
        new Thread(() -> {
            while (!getDone()) {
                count = count + 1;
            }
            System.out.println("DONE!!!!");
        }).start();
            Thread.sleep(5000);
        System.out.println("Changing done");
        synchronized (Main.class) {
            done = true;
        }
    }

    public static boolean getDone() {
        return done;
    }
}

如果不同步訪問done正確的,這意味着你的代碼可能會失敗,即線程可能不會看到更新后的值。

除非正確同步,否則並不意味着保證值不可見。 因此,在許多情況下,寫入done仍然可見(在許多情況下,破壞的代碼仍然有效,這使得並發編程更加困難)。 它並不能保證在每種情況下都能正常工作。

我沒有getDone方法同步。 我有什么想法為線程完成處理。

正如您所提到的,在旋轉線程和主線程看到的done之間沒有明確的內存同步。 雖然主線程在退出synchronized塊時穿過寫入內存屏障,但是旋轉線程沒有明確的讀取內存屏障。

但是,線程有很多方法可以查看更新的信息。 如果操作系統將線程交換出正在運行的處理器,則緩存的內存可能會丟失,因此當線程被交換回來時,它將從中央內存請求done並將看到更新。

此外,雖然您的示例代碼並沒有表現出來,如果您對其他調用synchronized方法(如System.out.println()或其他交叉內存屏障(訪問其他volatile場),那么這也將引起done到得到更新。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM