Java線程中的“交通規則”

線程就像現實世界裡複雜的交通線上運行的汽車,有停車讓行的,也有一路高歌的,甚至還有特殊情況優先行駛的情況,本文將一一介紹這些內容。

Java線程中的“交通規則”


【本文目標】

通過閱讀本節內容,你將學會使用join方法讓線程強制一直執行、使用yield方法禮讓其他線程優先執行,瞭解並學會設置線程的優先級使系統自動調度資源執行線程。

線程的強制執行

所謂的線程的強制執行指的是當滿足於某些條件之後,某一個線程對象將可以一直獨佔資源,一直到該線程的程序執行結束。範例:觀察一個沒有強制執行的程序

<code>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);
}
}
}/<code>


Java線程中的“交通規則”

圖一 沒有強制執行的程序

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

<code>強制執行 :public final void join(long millis) throws InterruptedException;/<code>
<code>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);
}
}
}/<code>


Java線程中的“交通規則”

圖二 強制執行

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

線程禮讓

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

<code>public static void yield();/<code>

範例:使用禮讓操作

<code>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);
}
}
}/<code>


Java線程中的“交通規則”

圖三 禮讓線程

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

線程優先級

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

<code>設置優先級:public final void setPriority(int newPriority);
獲取優先級:public final int getPriority();/<code>

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

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

範例:觀察優先級

<code>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();
}
}/<code>


Java線程中的“交通規則”

圖四 線程優先級執行

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

<code>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
}
}/<code>

主線程屬於中等優先級,而默認創建的線程也是中等優先級。


分享到:


相關文章: