日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關咨詢
選擇下列產(chǎn)品馬上在線溝通
服務時間:8:30-17:00
你可能遇到了下面的問題
關閉右側工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
面試官:有了解過線程組和線程優(yōu)先級嗎?

什么是線程組

public class ThreadGroupTest {
public static void main(String[] args) {
new Thread(() -> {
System.out.println(Thread.currentThread().getThreadGroup().getName());
}).start();
System.out.println(Thread.currentThread().getThreadGroup().getName());
}
}

輸出:

main
main

可以發(fā)現(xiàn)在main線程組下;

ThreadGroup是一個標準的「向下引用」的樹狀結構,這樣設計的原因是「防止"上級"線程被"下級"線程引用而無法有效地被GC回收」。

線程優(yōu)先級

線程的優(yōu)先級級別由操作系統(tǒng)決定,不同的操作系統(tǒng)級別是不一樣的,在Java中,提供了一個級別范圍1~10,方便我們?nèi)⒖?。Java默認的線程優(yōu)先級為5,線程的執(zhí)行順序由調(diào)度程序來決定,線程的優(yōu)先級會在線程被調(diào)用之前設定。

源碼描述:

/**
* 最低級別
*/
public final static int MIN_PRIORITY = 1;

/**
* 默認級別
*/
public final static int NORM_PRIORITY = 5;

/**
* 最高級別
*/
public final static int MAX_PRIORITY = 10;

獲取線程優(yōu)先級別

public static void main(String[] args) {
new Thread(() -> {
System.out.println("default level: {}" + Thread.currentThread().getPriority());
}).start();
}

輸出: default level: {}5

設置級別

public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("default level: {}" + Thread.currentThread().getPriority());
});
t.start();
t.setPriority(10);
}

輸出: default level: {}10

通常來講,高級別的優(yōu)先級往往會更高幾率的執(zhí)行,注意這里是概率性問題,下面我們測試一下:

public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
});
t.setPriority(3);

Thread t1 = new Thread(() -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
});
t1.setPriority(7);

Thread t2 = new Thread(() -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
});
t2.setPriority(10);


t.start();
t1.start();
t2.start();
}

第一次輸出:

hello 7
default level: {}7
hello 10
default level: {}10
hello 3
default level: {}3

第二次:

hello 3
default level: {}3
hello 7
default level: {}7
hello 10
default level: {}10

第三次

hello 10
default level: {}10
hello 7
default level: {}7
hello 3
default level: {}3

...

發(fā)現(xiàn),不斷的嘗試之后,高級別出現(xiàn)的概率會比較靠前一點, 所以想要借助它來完成一些特定業(yè)務的同學注意了,不建議使用,不靠譜,之前也講到,底層還是由操作系統(tǒng)調(diào)度完成

Java提供一個「線程調(diào)度器」來監(jiān)視和控制處于「RUNNABLE狀態(tài)」的線程。線程的調(diào)度策略采用「搶占式」,優(yōu)先級高的線程比優(yōu)先級低的線程會有更大的幾率優(yōu)先執(zhí)行。在優(yōu)先級相同的情況下,按照“先到先得”的原則。每個Java程序都有一個默認的主線程,就是通過JVM啟動的第一個線程main線程。

除了主線程之外,還有一個線程是守護線程,它的優(yōu)先級比較低。如果所有的非守護線程都結束了,這個守護線程也會自動結束??梢越柚鼘崿F(xiàn)一些特定場景,比如手動關閉線程的場景,某些場景下不關閉,會造成資源浪費,手動關閉又很麻煩。這里我們可以通過setDaemon(true)指定。

public static void main(String[] args) {
Thread t = new Thread(() -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
});
t.setDaemon(true); // 默認為false
t.setPriority(10);

Thread t1 = new Thread(() -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
});
t1.setPriority(7);

t.start();
t1.start();
}

輸出:

hello 7
default level: {}7
hello 10
default level: {}10

發(fā)現(xiàn)即使指定了高級別,執(zhí)行的優(yōu)先級仍然是最低的

線程組下的優(yōu)先級

剛剛我們都是在main線程組下,舉一反三,線程組下的優(yōu)先級又是怎么樣的呢下面,測試一下:

public static void main(String[] args) {
// 指定 name 為 g1的線程組
ThreadGroup group = new ThreadGroup("g1");
group.setMaxPriority(4);

Thread t = new Thread(group, () -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
}, "t0");
t.setPriority(10);
t.start();
}

輸出:

hello 4
default level: {}4

發(fā)現(xiàn),在g1線程組下指定了最大優(yōu)先級后,線程t0的優(yōu)先級最大級別只能是4, 所以這也是使用線程組的好處。

我們可以通過如下方式復制線程組, ThreadGroup提供了enumerate方法:

public static void main(String[] args) throws InterruptedException {
// 指定 name 為 g1的線程組
ThreadGroup group = new ThreadGroup("g1");
group.setMaxPriority(4);

Thread t = new Thread(group, () -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
}, "t0");
t.setPriority(10);
t.start();

// 復制線程組
System.out.println(group.activeCount()); // 1
Thread[] list = new Thread[group.activeCount()];
group.enumerate(list);

Thread.sleep(3000);
System.out.println(list[0].getName()); // 輸出 t0

}

統(tǒng)一異常捕獲

public static void main(String[] args) {
// 指定 name 為 g1的線程組
ThreadGroup group = new ThreadGroup("g1") {
// 統(tǒng)一異常捕獲
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + ": " + e.getMessage()); // t0: 我出錯了
}
};
group.setMaxPriority(4);

Thread t = new Thread(group, () -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
throw new RuntimeException("我出錯了");
}, "t0");
t.setPriority(10);
t.start();
}

向下引用的樹狀數(shù)據(jù)結構

線程組的內(nèi)部其實不單單可以放線程,其實也可以放其它線程組,我們看下源碼定義

 public static void main(String[] args) {
// 指定 name 為 g1的線程組
ThreadGroup group = new ThreadGroup("g1") {
// 統(tǒng)一異常捕獲
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + ": " + e.getMessage()); // t0: 我出錯了
}
};
group.setMaxPriority(4);

Thread t = new Thread(group, () -> {
System.out.println("hello " + Thread.currentThread().getPriority());
System.out.println("default level: {}" + Thread.currentThread().getPriority());
throw new RuntimeException("我出錯了");
}, "t0");
t.setPriority(10);
t.start();
}

這里大家可以大膽去猜測一下,為什么要采用這種數(shù)據(jù)結構其實你通過源碼發(fā)現(xiàn),它的內(nèi)部很多地方都調(diào)用了checkAccess方法,特別是在set操作,字面意思是檢查是否有權限,我看下這個方法。

public final void checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}

它調(diào)用了一個SecurityManager, 它是Java的安全管理器,它允許應用程序在執(zhí)行一個可能不安全或敏感的操作前確定該操作是什么,以及是否是在允許執(zhí)行該操作的安全上下文中執(zhí)行它。應用程序可以允許或不允許該操作??偟膩碚f就是保證安全性。

通過上面的了解,我們應該知道為什么要用這種樹狀結構了。它都是一層一層級別的控制,這么做方便去管理,提高安全性,出了問題也能很快的定位到。就像公司的人員組織架構一樣,一切都是為了管理好公司。

結束語

本篇內(nèi)容到這里就結束了, 大家自己一定要多去理解,不要去背,。


網(wǎng)頁名稱:面試官:有了解過線程組和線程優(yōu)先級嗎?
URL鏈接:http://www.5511xx.com/article/djcgdsp.html