• <ruby id="bi9vj"><b id="bi9vj"></b></ruby>

        <b id="bi9vj"></b>

        java while不會退出

        洗襪子的少年 發布于 昨天 16:47
        閱讀 198
        收藏 0

        static boolean done = false;
        public static void main(String[] args) {
            new Thread(() -> {
                while (!done);
                System.out.println("exited----");
            }).start();

            new Thread(() -> {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                done = true;
                System.out.println("exiting----");
            }).start();
        }

        求教:為什么第一個線程的while不會退出?

        加載中
        0
        洗襪子的少年
        洗襪子的少年
        哪位大佬可以幫忙解釋下
        0
        天天向上zhougf
        天天向上zhougf

        為什么不會? 會啊

        洗襪子的少年
        洗襪子的少年
        應該是while后邊沒有加分號:joy:
        洗襪子的少年
        洗襪子的少年
        你可以試下,我這試的是不會退出的
        s
        solo丶慕顏
        。。。 為什么你會有那么多的exited? while 后面的分號沒加吧。。。
        0
        堅強的小二

        加個 volatile 試試

        static volatile boolean done = false;

        0
        h
        hbyckyle

        這肯定不會退出啊 讀到變量表里面是false 你用

        volatile static boolean done = false

        就可以了

        洗襪子的少年
        洗襪子的少年
        while(!done){ System.out.print("");}這樣是可以的:sweat_smile:
        洗襪子的少年
        洗襪子的少年
        但是在循環體里寫一個打印語句,或sleep下就可以的
        0
        溫安適
        溫安適
        volatile static boolean done = false

        volatile 保證可見性,否則第二個線程的修改第一個線程看不見

        溫安適
        溫安適
        回復 @洗襪子的少年 : System.out.print("")或者sleep(1),這就有時間差了,在這個時間差后,第一個線程就能看到第二個線程修改的值了。
        洗襪子的少年
        洗襪子的少年
        while(!done){ System.out.print("");}這樣或者循環體里slee(1)就可以退出
        0
        谷歌火狐和IE

        如果循環體執行很快,比如循環體為空,Java內存模型會把變量的值緩存起來,導致別的線程更新后,當前線程無法看到變量最新的值,所以循環會一直不退出。

        System.out.print("")或者sleep(1)都是比較耗時的操作,print調用的IO相關的API

        以上均是瞎猜??

        0
        tcxu
        tcxu

        預備知識:
        JMM(Java 內存模型)定義了Java 虛擬機(JVM)在計算機內存(RAM)中的工作方式。
        線程之間的共享變量存儲在主內存(Main Memory)中,每個線程都有一個私有的本地內存(Local Memory),本地內存中存儲了該線程以讀/寫共享變量的副本。本地內存是 JMM 的一個抽象概念,并不真實存在。它涵蓋了緩存、寫緩沖區、寄存器以及其他的硬件和編譯器優化。

        樓主的案例場景如圖,說明如下。

        1. static boolean done = false; 表明,done 是主方法啟動的兩個線程 (這里依次成為 A 與 B) 的共享屬性/內存。它存于主內存。
        2. done 初始值為 false。第一個線程 A 運行,將主內存里的 done,復制到它的工作內存(本地內存A)。由于本地內存A里的 done 始終是 false,導致 執行 while (!done);  成了死循環, 所以不會跳出while 循環,退出。
        3. done 初始值為 false。第二個線程 B 運行,將主內存里的 done,復制到它的工作內存(本地內存B)。隨后,線程 B 啟動,將本地內存B里的 done 變為 true。但這種變更,改變不了主內存和本地內存A中的 done。就是說,不可能終止第一個線程(A)的while循環。

        樓上,堅強的小二、hbyckyle、溫安適 等 建議 添加關鍵詞 volatile 的 辦法,確實可行。

        參考:
        JMM和底層實現原理

        Java中volatile關鍵字的最全總結

         

         

        返回頂部
        頂部
        聚看影院