<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                <!-- Terminating Long-Running Tasks --> ## 終止耗時任務 并發程序通常使用長時間運行的任務。可調用任務在完成時返回值;雖然這給它一個有限的壽命,但仍然可能很長。可運行的任務有時被設置為永遠運行的后臺進程。你經常需要一種方法在正常完成之前停止**Runnable**和**Callable**任務,例如當你關閉程序時。 最初的Java設計提供了中斷運行任務的機制(為了向后兼容,仍然存在);中斷機制包括阻塞問題。中斷任務既亂又復雜,因為你必須了解可能發生中斷的所有可能狀態,以及可能導致的數據丟失。使用中斷被視為反對模式,但我們仍然被迫接受。 InterruptedException,因為設計的向后兼容性殘留。 任務終止的最佳方法是設置任務周期性檢查的標志。然后任務可以通過自己的shutdown進程并正常終止。不是在任務中隨機關閉線程,而是要求任務在到達了一個較好時自行終止。這總是產生比中斷更好的結果,以及更容易理解的更合理的代碼。 以這種方式終止任務聽起來很簡單:設置任務可以看到的**boolean** flag。編寫任務,以便定期檢查標志并執行正常終止。這實際上就是你所做的,但是有一個復雜的問題:我們的舊克星,共同的可變狀態。如果該標志可以被另一個任務操縱,則存在碰撞可能性。 在研究Java文獻時,你會發現很多解決這個問題的方法,經常使用**volatile**關鍵字。我們將使用更簡單的技術并避免所有易變的參數,這些都在[附錄:低級并發](./Appendix-Low-Level-Concurrency.md)中有所涉及。 Java 5引入了**Atomic**類,它提供了一組可以使用的類型,而不必擔心并發問題。我們將添加**AtomicBoolean**標志,告訴任務清理自己并退出。 ```java // concurrent/QuittableTask.java import java.util.concurrent.atomic.AtomicBoolean;import onjava.Nap; public class QuittableTask implements Runnable { final int id; public QuittableTask(int id) { this.id = id; } private AtomicBoolean running = new AtomicBoolean(true); public void quit() { running.set(false); } @Override public void run() { while(running.get()) // [1] new Nap(0.1); System.out.print(id + " "); // [2] } } ``` 雖然多個任務可以在同一個實例上成功調用**quit()**,但是**AtomicBoolean**可以防止多個任務同時實際修改**running**,從而使**quit()**方法成為線程安全的。 - [1]:只要運行標志為true,此任務的run()方法將繼續。 - [2]: 顯示僅在任務退出時發生。 需要**running AtomicBoolean**證明編寫Java program并發時最基本的困難之一是,如果**running**是一個普通的布爾值,你可能無法在執行程序中看到問題。實際上,在這個例子中,你可能永遠不會有任何問題 - 但是代碼仍然是不安全的。編寫表明該問題的測試可能很困難或不可能。因此,你沒有任何反饋來告訴你已經做錯了。通常,你編寫線程安全代碼的唯一方法就是通過了解事情可能出錯的所有細微之處。 作為測試,我們將啟動很多QuittableTasks然后關閉它們。嘗試使用較大的COUNT值 ```java // concurrent/QuittingTasks.java import java.util.*; import java.util.stream.*; import java.util.concurrent.*; import onjava.Nap; public class QuittingTasks { public static final int COUNT = 150; public static void main(String[] args) { ExecutorService es = Executors.newCachedThreadPool(); List<QuittableTask> tasks = IntStream.range(1, COUNT) .mapToObj(QuittableTask::new) .peek(qt -> es.execute(qt)) .collect(Collectors.toList()); new Nap(1); tasks.forEach(QuittableTask::quit); es.shutdown(); } } ``` 輸出結果: ``` 24 27 31 8 11 7 19 12 16 4 23 3 28 32 15 20 63 60 68 6764 39 47 52 51 55 40 43 48 59 44 56 36 35 71 72 83 10396 92 88 99 100 87 91 79 75 84 76 115 108 112 104 107111 95 80 147 120 127 119 123 144 143 116 132 124 128 136 131 135 139 148 140 2 126 6 5 1 18 129 17 14 13 2122 9 10 30 33 58 37 125 26 34 133 145 78 137 141 138 6274 142 86 65 73 146 70 42 149 121 110 134 105 82 117106 113 122 45 114 118 38 50 29 90 101 89 57 53 94 4161 66 130 69 77 81 85 93 25 102 54 109 98 49 46 97 ``` 我使用**peek()**將**QuittableTasks**傳遞給**ExecutorService**,然后將這些任務收集到**List.main()**中,只要任何任務仍在運行,就會阻止程序退出。即使為每個任務按順序調用quit()方法,任務也不會按照它們創建的順序關閉。獨立運行的任務不會確定性地響應信號。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看