<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Java 并發性 – `yield()`和`join()`之間的區別 > 原文: [https://howtodoinjava.com/java/multi-threading/difference-between-yield-and-join-in-threads-in-java/](https://howtodoinjava.com/java/multi-threading/difference-between-yield-and-join-in-threads-in-java/) [**多線程**](//howtodoinjava.com/category/java/multi-threading/ "multi-threading")從很長時間以來一直是[**面試官**](//howtodoinjava.com/java-interview-questions/ "java interviews")中非常受歡迎的話題。 盡管我個人覺得很少有人真正有機會在復雜的多線程應用程序上工作(*在過去的 7 年中只有一次機會*),但仍然可以幫助您方便地掌握這些概念來僅僅增強您的信心。 之前,我討論過一個類似的問題,關于[**`wait()`和`sleep()`方法之間的區別**](//howtodoinjava.com/java/multi-threading/difference-between-sleep-and-wait/ "wait and sleep"),這一次,我正在討論`join()`和`yield()`方法之間的**區別** 。 坦白地說,我在實踐中并未同時使用這兩種方法,因此,如果您在任何時候都感到不滿意,請提出意見。 ## Java 線程調度的一些背景知識 需要 Java 虛擬機在其各個線程之間實現**可搶占,基于優先級的調度器**。 這意味著為 Java 程序中的每個線程分配了一定的優先級,該優先級在明確定義的范圍內。 開發人員可以更改此*優先級。 Java 虛擬機永遠不會更改線程的優先級,即使該線程已經運行了一段時間。* 優先級值很重要,因為 Java 虛擬機和底層操作系統之間的約定是**操作系統通常必須選擇以最高優先級**運行 Java 線程。 這就是說 Java 實現基于優先級的[**調度器**](https://en.wikipedia.org/wiki/Fixed-priority_pre-emptive_scheduling "preemptive scheduling")時的意思。 此調度器以搶先方式實現,這意味著,當有一個優先級較低的線程正在運行時,當出現優先級較高的線程時,該線程中斷(***會搶占***)。 但是,與操作系統的契約不是絕對的,這意味著操作系統有時可以選擇運行優先級較低的線程。(我討厭有關多線程的問題。) > 還要注意, **java 并沒有要求對其線程進行時間分段**,但大多數操作系統都這樣做。 這里的術語經常會有一些混亂:搶占經常與時間片混淆。 實際上,**搶占僅意味著運行優先級更高的線程而不是優先級較低的線程**,但是當線程具有相同優先級時,它們不會相互搶占。 它們通常受時間限制,但這不是 Java 的要求。 ## 了解線程優先級 了解線程優先級是學習多線程的下一個重要步驟,尤其是 **`yield()`的工作方式**。 1. 請記住,未指定優先級時,所有線程均具有正常優先級。 2. 優先級可以在 1 到 10 之間指定。10 是最高優先級,1 是最低優先級,5 是正常優先級。 3. 請記住,優先級最高的線程將在執行時被賦予優先級。 但是不能保證它一開始就處于運行狀態。 4. 與正在等待機會的池中的線程相比,當前正在執行的線程始終始終具有更高的優先級。 5. 線程調度器決定應該執行哪個線程。 6. `t.setPriority()`可用于設置線程的優先級。 7. 請記住,應該在調用線程啟動方法之前設置優先級。 8. 您可以使用常量`MIN_PRIORITY`,`MAX_PRIORITY`和`NORM_PRIORITY`設置優先級。 現在,當我們對線程調度和線程優先級有了一些基本了解時,讓我們進入主題。 ## `yield()`方法 從理論上講,**`yield()`是指放棄,屈服,投降**。 一個讓步線程告訴虛擬機,它愿意讓其他線程在其位置進行調度。 這表明它并沒有做太重要的事情。 請注意,雖然*只是提示*,但不能保證完全有效。 `yield()`在`Thread.java`中定義如下。 ```java /** * A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore * this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU. * Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect. */ public static native void yield(); ``` 讓我們從上面的定義中列出要點: * 產量也是靜態方法,也是本機方法。 * `Yield`告訴當前正在執行的線程給[**線程池**](//howtodoinjava.com/java-5/java-executor-framework-tutorial-and-best-practices/ "thread pool")中具有相同優先級的線程一個機會。 * 無法保證`Yield`將使當前正在執行的線程立即變為可運行狀態。 * 它只能使線程從運行狀態變為可運行狀態,而不能處于等待或阻塞狀態。 ## `yield()`方法示例用法 在下面的示例程序中,我沒有特定的原因創建了兩個名為生產者和消費者的線程。 生產者設置為最小優先級,而消費者設置為最大優先級。 我將在有/無注釋行`Thread.yield()`的情況下運行以下代碼。 如果沒有`yield()`,盡管輸出有時會更改,但是通常首先打印所有使用者行,然后才打印所有生產者行。 使用`yield()`方法,兩者都一次打印一行,并且幾乎總是將機會傳遞給另一線程。 ```java package test.core.threads; public class YieldExample { public static void main(String[] args) { Thread producer = new Producer(); Thread consumer = new Consumer(); producer.setPriority(Thread.MIN_PRIORITY); //Min Priority consumer.setPriority(Thread.MAX_PRIORITY); //Max Priority producer.start(); consumer.start(); } } class Producer extends Thread { public void run() { for (int i = 0; i < 5; i++) { System.out.println("I am Producer : Produced Item " + i); Thread.yield(); } } } class Consumer extends Thread { public void run() { for (int i = 0; i < 5; i++) { System.out.println("I am Consumer : Consumed Item " + i); Thread.yield(); } } } ``` #### 上面程序的輸出,“沒有”`yield()`方法 ```java I am Consumer : Consumed Item 0 I am Consumer : Consumed Item 1 I am Consumer : Consumed Item 2 I am Consumer : Consumed Item 3 I am Consumer : Consumed Item 4 I am Producer : Produced Item 0 I am Producer : Produced Item 1 I am Producer : Produced Item 2 I am Producer : Produced Item 3 I am Producer : Produced Item 4 ``` #### 添加了`yield()`后上述程序方法的輸出 ```java I am Producer : Produced Item 0 I am Consumer : Consumed Item 0 I am Producer : Produced Item 1 I am Consumer : Consumed Item 1 I am Producer : Produced Item 2 I am Consumer : Consumed Item 2 I am Producer : Produced Item 3 I am Consumer : Consumed Item 3 I am Producer : Produced Item 4 I am Consumer : Consumed Item 4 ``` ## `join()`方法 可以將`Thread`實例的`join()`方法用于將一個線程的執行開始“連接”到另一個線程的執行的結束,這樣一個線程只有在另一個線程結束后才能開始運行。 如果在`Thread`實例上調用`join()`,則當前正在運行的線程將阻塞,直到`Thread`實例完成執行為止。 ```java //Waits for this thread to die. public final void join() throws InterruptedException ``` ***在`join()`中設置超時,將使特定超時后的`join()`效果無效***。當達到超時時,主線程和`taskThread`都是執行任務的同等可能性。 但是,與睡眠一樣,`join`的運行時間也取決于操作系統,因此,您不應假定`join`會完全按照您指定的時間等待。 像睡眠一樣,`join`通過退出`InterruptedException`來響應中斷。 ## `join()`方法示例用法 ```java package test.core.threads; public class JoinExample { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(new Runnable() { public void run() { System.out.println("First task started"); System.out.println("Sleeping for 2 seconds"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("First task completed"); } }); Thread t1 = new Thread(new Runnable() { public void run() { System.out.println("Second task completed"); } }); t.start(); // Line 15 t.join(); // Line 16 t1.start(); } } Output: First task started Sleeping for 2 seconds First task completed Second task completed ``` 僅此一個很小但很重要的概念。 在評論部分讓我知道您的想法。 **祝您學習愉快!**
                  <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>

                              哎呀哎呀视频在线观看