1、線程各屬性縱覽
屬性名稱 | 用戶 |
---|---|
編號(ID) | 每個線程有自己的ID,用於標識不同的線程 |
名稱(Name) | 作用讓用戶或程序員在開發、調試或運行過程中,更容易區分每個不同的線程、定位問題等 |
是否是守護線程(isDaemon) | true代表該線程是【守護線程】,false代表線程是非守護線程,也就是【用戶線程】 |
優先級(Priority) | 優先級這個屬性的目的是告訴線程調度器,用戶希望哪些線程相對多運行、哪些少運行 |
2、線程ID
/**
* Id
*
* @author venlenter
* @Description: ID從1開始,JVM運行起來後,我們自己創建的線程的ID早已不是2
* @since unknown, 2020-04-26
*/
public class Id {
public static void main(String[] args) {
Thread thread = new Thread();
System.out.println("主線程id:" + Thread.currentThread().getId());
System.out.println("子線程id:" + thread.getId());
}
}
//輸出結果
主線程id:1
子線程id:11
//getId內部調用是nextThreadID
//thread.getId = nextThreadID()
//private static synchronized long nextThreadID() {
// return ++threadSeqNumber;
// }
3、線程名字、守護線程
3.1 線程名字
3.1.1 默認線程名字源碼分析
- "Thread-" + 自增數
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
3.1.2 修改線程的名字(代碼演示、源碼分析)
Thread thread = new Thread();
System.out.println("子線程初始名字:" + thread.getName());
thread.setName("FlyThread-1");
System.out.println("子線程修改後的名字:" + thread.getName());
//輸出結果
子線程初始名字:Thread-0
子線程修改後的名字:FlyThread-1
3.2 守護線程
3.2.1 作用:給用戶線程提供服務
3.2.2 三個特性
- 線程類型默認繼承自父線程(守護線程的子線程也是守護線程)
- 通常守護線程都是由JVM自動啓動的
- 不影響JVM退出:JVM退出只會考慮是否還有用戶線程
3.2.3 守護線程的常見面試問題
(1)守護線程和普通線程的區別
- 整體無區別
- 唯一區別在於JVM的離開:用戶線程會影響JVM的停止,而守護線程不影響
- 作用不同:用戶線程是執行邏輯的,而守護線程是給用戶線程提供服務的
(2)我們是否需要給線程設置爲守護線程?thread.setDaemon(true);
- 不應該把自己的用戶線程設置爲守護線程。
- 例如:如果設置了用戶線程爲守護線程,JVM發現只有一個守護線程,就中止退出了,導致程序邏輯沒有走完。
- 其實JVM本身提供的守護線程就已經足夠了
4、線程優先級
10個級別,默認5
- 引申面試題:我們應該如何應用線程優先級來幫助程序運行?有哪些禁忌?
- 不同的操作系統如何處理優先級問題?
程序設計不應依賴於優先級
- 不同操作系統不一樣
- 優先級會被操作系統改變
5、各屬性總結
屬性名稱 | 用途 | 注意事項 |
---|---|---|
編號(ID) | 標識不同的線程 | 線程回收後,id被後續創建的線程使用;無法保證id的唯一性(之前線程id,跟後續線程id不一定是同一個線程,可能是回收後後續創建的);不允許修改id |
名稱(Name) | 定位問題 | 可以設置一個清晰有意義的名字(方便跟蹤定位);默認的名稱是Thread-0/1/2/3 |
是否是守護線程(isDaemon) | 守護線程/用戶線程 | 二選一;繼承父線程;setDaemon |
優先級(Priority) | 告訴線程調度器,哪些線程相對多運行、哪些少運行 | 默認和父線程的優先級相等,共有10個等級,默認5;不應依賴優先級 |
筆記來源:慕課網悟空老師視頻《Java併發核心知識體系精講》