天天看點

迅速讀懂Java線程的交通規則 | 帶你學《Java語言進階特性》之八

上一篇:教你随心操控線程狀态 | 帶你學《Java語言進階特性》之七

【本節目标】

通過閱讀本節内容,你将學會使用join方法讓線程強制一直執行、使用yield方法禮讓其他線程優先執行,了解并學會設定線程的優先級使系統自動排程資源執行線程。

線程的強制執行

所謂的線程的強制執行指的是當滿足于某些條件之後,某一個線程對象将可以一直獨占資源,一直到該線程的程式執行結束。

範例:觀察一個沒有強制執行的程式

public class ThreadDemo {
   public static void main(String[] args) throws Exception {
       Thread thread = new Thread(() -> {
           for (int x = 0; x < 100; x++) {
               try {
                   Thread.sleep(100);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println(Thread.currentThread().getName() + "執行、x = " + x);
           }
       }, "玩耍的線程");
       thread.start();
       for (int x = 0; x < 100; x++) {
           Thread.sleep(100);
           System.out.println("【霸道的main線程】number = " + x);
       }
   }
}           
迅速讀懂Java線程的交通規則 | 帶你學《Java語言進階特性》之八

圖一 沒有強制執行的程式

這個時候主線程和子線程都在交替執行着,但是如果說現在希望主線程獨占執行,那麼就可以用Thread類中的方法:

強制執行 :public final void join(long millis) throws InterruptedException;           
public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Thread mainThread = Thread.currentThread();    //獲得主線程
        Thread thread = new Thread(() -> {
            for (int x = 0; x < 100; x++) {
                if (x == 3) {      //現在霸道的線程來了
                    try {
                        mainThread.join();    //霸道的線程要先執行
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "執行、x = " + x);
            }
        }, "玩耍的線程");
        thread.start();
        for (int x = 0; x < 100; x++) {
            Thread.sleep(100);
            System.out.println("【霸道的main線程】number = " + x);
        }
    }
}           
迅速讀懂Java線程的交通規則 | 帶你學《Java語言進階特性》之八

圖二 強制執行

在進行線程強制執行的時候,一定要擷取強制執行線程對象之後才可以執行join()的調用。

線程禮讓

線程的禮讓指的是先将資源讓出去讓别的線程先執行。線程的禮讓可以使用Thread類中提供的方法:

public static void yield();           

範例:使用禮讓操作

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(() -> {
            for (int x = 0; x < 100; x++) {
                if(x%3==0){
                    Thread.yield();      //線程禮讓
                    System.out.println("### 玩耍的線程禮讓執行 ###");
                }
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "執行、x = " + x);
            }
        }, "玩耍的線程");
        thread.start();
        for (int x = 0; x < 100; x++) {
            Thread.sleep(100);
            System.out.println("【霸道的main線程】number = " + x);
        }
    }
}           
迅速讀懂Java線程的交通規則 | 帶你學《Java語言進階特性》之八

圖三 禮讓線程

禮讓執行的時候每一次調用yield()方法都隻會禮讓一次目前的資源。

線程優先級

從理論上來講,線程的優先級越高,越有可能先執行(越有可能先搶占到資源)。在Thread類中針對優先級的操作提供有如下兩個處理方法:

設定優先級:public final void setPriority(int newPriority);
擷取優先級:public final int getPriority();           

在進行優先級定義的時候都是通過int型的數字來完成的,而對于此數字的選擇在Thread類中就定義了三個常量:

最高優先級:public static final int MAX_PRIORITY 、10;
中等優先級:public static final int NORM_PRIORITY 、5;
最低優先級:public static final int MIN_PRIORITY 、1;           

範例:觀察優先級

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Runnable run = () -> {
            for (int x = 0; x < 10; x++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "執行。");
            }
        };
        Thread threadA = new Thread(run, "線程對象A");
        Thread threadB = new Thread(run, "線程對象B");
        Thread threadC = new Thread(run, "線程對象C");
        threadA.setPriority(Thread.MIN_PRIORITY);
        threadB.setPriority(Thread.MIN_PRIORITY);
        threadC.setPriority(Thread.MAX_PRIORITY);
        threadA.start();
        threadB.start();
        threadC.start();
    }
}           
迅速讀懂Java線程的交通規則 | 帶你學《Java語言進階特性》之八

圖四 線程優先級執行

主方法是一個主線程,那麼主線程的優先級呢?預設線程對象的優先級呢?

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        System.out.println(Thread.currentThread().getPriority());    //5
        System.out.println(new Thread().currentThread().getPriority());    //5
    }
}           

主線程屬于中等優先級,而預設建立的線程也是中等優先級。

想學習更多的Java的課程嗎?從小白到大神,從入門到精通,更多精彩不容錯過!免費為您提供更多的學習資源。

本内容視訊來源于

阿裡雲大學 下一篇:使用同步解決多人賣票問題 | 帶你學《Java語言進階特性》之九 更多Java面向對象程式設計文章檢視此處