小宋帶大家繼續深入多執行緒的學習,本章講解一下關于執行緒組以及執行緒優先級的相關知識,
目錄
- 執行緒組
- 執行緒的優先級
- 執行緒組的常用方法及資料結構
- 執行緒組的常用方法
- 執行緒組的資料結構
執行緒組
我們先普及一下執行緒組的概念,
java中用ThreadGroup來表示執行緒組,我們可以使用執行緒組對執行緒進行批量操作,
ThreadGroup和Thread的關系就如同他們的字面意思,每個Thread必然存在于一個ThreadGroup中,Thread不能獨立于ThreadGroup存在,執行main()方法執行緒的名字是main,如果在new Thread時沒有顯示指定,那么默認將父執行緒(當前執行new Thread的執行緒)執行緒組設定為自己的執行緒組,
eg.
public class Demo {
public static void main(String[] args) {
Thread testThread = new Thread(() -> {
System.out.println("testThread當前執行緒組名字:" +
Thread.currentThread().getThreadGroup().getName());
System.out.println("testThread執行緒名字:" +
Thread.currentThread().getName());
});
testThread.start();
System.out.println("執行main所在執行緒的執行緒組名字: " + Thread.currentThread().getThreadGroup().getName());
System.out.println("執行main方法執行緒名字:" + Thread.currentThread().getName());
}
}
輸出:
執行main所在執行緒的執行緒組名字: main
執行main方法執行緒名字:main
testThread當前執行緒組名字:main
testThread執行緒名字:Thread-0
ThreadGroup管理者它下面的Thread,ThreadGroup是一個標準的向下參考的樹狀結構,這樣設計的原因是防止上級執行緒被下級執行緒參考而無法有效地被GC回收
執行緒的優先級
Java中執行緒優先級可以指定,范圍是1~10,但是并不是所有的作業系統都支持10級優先級的劃分(比如有些作業系統只支持3級劃分:低->中->高),Java只是給作業系統一個優先級的參考值,執行緒最終在作業系統的優先級是多少還是由作業系統決定,
Java默認的執行緒優先級為5,執行緒的執行順序由調度程式來決定,執行緒的優先級會在執行緒被呼叫之前設定,
通常情況下,高優先級的執行緒將會比低優先級的執行緒有更高的幾率得到執行,我們使用方法Thread類的setPriority()實體方法來設定執行緒的優先級,
eg.
public class Demo {
public static void main(String[] args) {
Thread a = new Thread();
System.out.println("我是默認執行緒優先級:"+a.getPriority());
Thread b = new Thread();
b.setPriority(10);
System.out.println("我是設定過的執行緒優先級:"+b.getPriority());
}
}
輸出:
我是默認執行緒優先級:5
我是設定過的執行緒優先級:10
既然有1-10的級別來設定了執行緒的優先級,那么我們是不是可以在業務實作的時候,采用這種方式來指定一些執行緒執行的先后順序?
答案是:不行!
在上面的時候就有強調過一個點,Java中的優先級不是特別的可靠,因為Java程式中對執行緒所設定的優先級只是給作業系統一個建議,作業系統不一定會采納,真正的呼叫順序,是由作業系統的執行緒調度演算法決定的,
eg.
public class Demo {
public static class T1 extends Thread {
@Override
public void run() {
super.run();
System.out.println(String.format("當前執行的執行緒是:%s,優先級:%d",
Thread.currentThread().getName(),
Thread.currentThread().getPriority()));
}
}
public static void main(String[] args) {
IntStream.range(1, 10).forEach(i -> {
Thread thread = new Thread(new T1());
thread.setPriority(i);
thread.start();
});
}
}
輸出:
當前執行的執行緒是:Thread-17,優先級:9
當前執行的執行緒是:Thread-1,優先級:1
當前執行的執行緒是:Thread-13,優先級:7
當前執行的執行緒是:Thread-11,優先級:6
當前執行的執行緒是:Thread-15,優先級:8
當前執行的執行緒是:Thread-7,優先級:4
當前執行的執行緒是:Thread-9,優先級:5
當前執行的執行緒是:Thread-3,優先級:2
當前執行的執行緒是:Thread-5,優先級:3
Java提供一個執行緒調度器來監視和控制處于RUNNABLE狀態的執行緒,執行緒的調度策略采用搶占式,優先級高的執行緒比優先級低的執行緒會有更大的幾率優先執行,在優先級相同的情況下,按照先到先得的原則,每個Java程式都有一個默認的主執行緒,就是通過JVM啟動的第一個執行緒main執行緒,
還有一個執行緒叫守護執行緒(Daemon),守護執行緒的默認優先級比較低,
如果某個執行緒是守護執行緒的話,當所有的非守護執行緒都結束了,這個守護執行緒也會自動結束,
應用場景: 當所有非守護執行緒結束時,結束其余的子執行緒(守護執行緒)會自動關閉,就免去了還要繼續關閉子執行緒的麻煩,
一個執行緒默認是非守護執行緒,可以通過Thread類的setDaemon(boolean on)來設定,
上文說過一個執行緒必然存在于一個執行緒組當中,那么當執行緒和執行緒組的優先級不一致的時候會怎么樣呢?
eg.
public static void main(String[] args) {
ThreadGroup threadGroup = new ThreadGroup("t1");
threadGroup.setMaxPriority(6);
Thread thread = new Thread(threadGroup,"thread");
thread.setPriority(9);
System.out.println("我是執行緒組的優先級"+threadGroup.getName()+":"+threadGroup.getMaxPriority());
System.out.println("我是執行緒的優先級"+thread.getName()+":"+thread.getPriority());
}
輸出:
我是執行緒組的優先級t1:6
我是執行緒的優先級thread:6
所以,如果某個執行緒優先級大于執行緒所在執行緒組的最大優先級,那么該執行緒的優先級將會失效,取而代之的是執行緒組的最大優先級,
執行緒組的常用方法及資料結構
接著我們講一下執行緒組中有哪些常用的方法和它的資料結構
執行緒組的常用方法
- 獲取當前執行緒組的名字
Thread.currentThread.getThreadGroup.getName();
- 復制執行緒組
// 獲取當前的執行緒組
ThreadGroup threadGroup = Thread.currentThread().getThreadGroup();
// 復制一個執行緒組到一個執行緒陣列(獲取Thread資訊)
Thread[] threads = new Thread[threadGroup.activeCount()];
threadGroup.enumerate(threads);·
- 執行緒組統一例外處理
package com.func.axc.threadgroup;
public class ThreadGroupDemo {
public static void main(String[] args) {
ThreadGroup threadGroup1 = new ThreadGroup("group1") {
// 繼承ThreadGroup并重新定義以下方法
// 在執行緒成員拋出unchecked exception
// 會執行此方法
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + ": " + e.getMessage());
}
};
// 這個執行緒是threadGroup1的一員
Thread thread1 = new Thread(threadGroup1, new Runnable() {
public void run() {
// 拋出unchecked例外
throw new RuntimeException("測驗例外");
}
});
thread1.start();
}
}
執行緒組的資料結構
執行緒組還可以包含其他的執行緒組,不僅僅是執行緒,
看一下ThreadGroup原始碼的成員變數

private final ThreadGroup parent; // 父ThreadGroup
String name; // ThreadGroupr 的名稱
int maxPriority; // 執行緒組最大優先級
boolean destroyed; // 是否被銷毀
boolean daemon; // 是否守護執行緒
boolean vmAllowSuspension; // 是否可以中斷
int nUnstartedThreads = 0; // 還未啟動的執行緒
int nthreads; // ThreadGroup中執行緒數目
Thread threads[]; // ThreadGroup中的執行緒
int ngroups; // 執行緒組數目
ThreadGroup groups[]; // 執行緒組陣列
再看一下建構式:


第三個建構式里呼叫了checkParentAccess方法,看看這個方法的原始碼:

檢查parent ThreadGroup

判斷當前運行的執行緒是否具有修改執行緒組的權限
這里涉及到SecurityManager這個類,它是Java的安全管理器,它允許應用程式在執行一個可能不安全或敏感的操作前確定該操作是什么,以及是否是在允許執行該操作的安全背景關系中執行它,應用程式可以允許或不允許該操作,
比如引入了第三方類別庫,但是并不能保證它的安全性,
其實Thread類也有一個checkAccess()方法,不過是用來當前運行的執行緒是否有權限修改被呼叫的這個執行緒實體,(Determines if the currently running thread has permission to modify this thread.)
執行緒組是一個樹狀的結構,每個執行緒組下面可以有多個執行緒或者執行緒組,執行緒組可以起到統一控制執行緒的優先級和檢查執行緒的權限的作用,
講到這里本章對多執行緒系列之執行緒組和執行緒優先級的講解也就結束了,如果想了解更多知識可以在對應的專欄中看系列文章,謝謝大家的觀看,希望能給各位同學帶來幫助,如果覺得博主寫的還可以的,可以點贊收藏, 😉
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/240093.html
標籤:其他
下一篇:作業273:參照原型調整首頁
