<big id="yeiyz"><ruby id="yeiyz"></ruby></big>
    <track id="yeiyz"></track>
    <track id="yeiyz"></track>
    <p id="yeiyz"><del id="yeiyz"></del></p><td id="yeiyz"><option id="yeiyz"></option></td>
    1. <p id="yeiyz"></p>

      <td id="yeiyz"></td>

      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關鍵字的最全總結

       

       

      返回頂部
      頂部
      聚看影院