日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

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

新聞中心

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

什么是線(xiàn)程組

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線(xiàn)程組下;

ThreadGroup是一個(gè)標(biāo)準(zhǔn)的「向下引用」的樹(shù)狀結(jié)構(gòu),這樣設(shè)計(jì)的原因是「防止"上級(jí)"線(xiàn)程被"下級(jí)"線(xiàn)程引用而無(wú)法有效地被GC回收」。

線(xiàn)程優(yōu)先級(jí)

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

源碼描述:

/**
* 最低級(jí)別
*/
public final static int MIN_PRIORITY = 1;

/**
* 默認(rèn)級(jí)別
*/
public final static int NORM_PRIORITY = 5;

/**
* 最高級(jí)別
*/
public final static int MAX_PRIORITY = 10;

獲取線(xiàn)程優(yōu)先級(jí)別

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

輸出: default level: {}5

設(shè)置級(jí)別

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

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

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),不斷的嘗試之后,高級(jí)別出現(xiàn)的概率會(huì)比較靠前一點(diǎn), 所以想要借助它來(lái)完成一些特定業(yè)務(wù)的同學(xué)注意了,不建議使用,不靠譜,之前也講到,底層還是由操作系統(tǒng)調(diào)度完成

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

除了主線(xiàn)程之外,還有一個(gè)線(xiàn)程是守護(hù)線(xiàn)程,它的優(yōu)先級(jí)比較低。如果所有的非守護(hù)線(xiàn)程都結(jié)束了,這個(gè)守護(hù)線(xiàn)程也會(huì)自動(dòng)結(jié)束??梢越柚鼘?shí)現(xiàn)一些特定場(chǎng)景,比如手動(dòng)關(guān)閉線(xiàn)程的場(chǎng)景,某些場(chǎng)景下不關(guān)閉,會(huì)造成資源浪費(fèi),手動(dòng)關(guān)閉又很麻煩。這里我們可以通過(guò)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); // 默認(rèn)為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)即使指定了高級(jí)別,執(zhí)行的優(yōu)先級(jí)仍然是最低的

線(xiàn)程組下的優(yōu)先級(jí)

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

public static void main(String[] args) {
// 指定 name 為 g1的線(xiàn)程組
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線(xiàn)程組下指定了最大優(yōu)先級(jí)后,線(xiàn)程t0的優(yōu)先級(jí)最大級(jí)別只能是4, 所以這也是使用線(xiàn)程組的好處。

我們可以通過(guò)如下方式復(fù)制線(xiàn)程組, ThreadGroup提供了enumerate方法:

public static void main(String[] args) throws InterruptedException {
// 指定 name 為 g1的線(xiàn)程組
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();

// 復(fù)制線(xiàn)程組
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的線(xiàn)程組
ThreadGroup group = new ThreadGroup("g1") {
// 統(tǒng)一異常捕獲
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + ": " + e.getMessage()); // t0: 我出錯(cuò)了
}
};
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("我出錯(cuò)了");
}, "t0");
t.setPriority(10);
t.start();
}

向下引用的樹(shù)狀數(shù)據(jù)結(jié)構(gòu)

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

 public static void main(String[] args) {
// 指定 name 為 g1的線(xiàn)程組
ThreadGroup group = new ThreadGroup("g1") {
// 統(tǒng)一異常捕獲
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName() + ": " + e.getMessage()); // t0: 我出錯(cuò)了
}
};
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("我出錯(cuò)了");
}, "t0");
t.setPriority(10);
t.start();
}

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

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

它調(diào)用了一個(gè)SecurityManager, 它是Java的安全管理器,它允許應(yīng)用程序在執(zhí)行一個(gè)可能不安全或敏感的操作前確定該操作是什么,以及是否是在允許執(zhí)行該操作的安全上下文中執(zhí)行它。應(yīng)用程序可以允許或不允許該操作。總的來(lái)說(shuō)就是保證安全性。

通過(guò)上面的了解,我們應(yīng)該知道為什么要用這種樹(shù)狀結(jié)構(gòu)了。它都是一層一層級(jí)別的控制,這么做方便去管理,提高安全性,出了問(wèn)題也能很快的定位到。就像公司的人員組織架構(gòu)一樣,一切都是為了管理好公司。

結(jié)束語(yǔ)

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


文章題目:面試官:有了解過(guò)線(xiàn)程組和線(xiàn)程優(yōu)先級(jí)嗎?
鏈接分享:http://www.dlmjj.cn/article/djcgdsp.html