中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解java高并發的用戶線程和守護線程

發布時間:2021-10-27 11:06:34 來源:億速云 閱讀:133 作者:iii 欄目:開發技術

這篇文章主要講解了“怎么理解java高并發的用戶線程和守護線程”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么理解java高并發的用戶線程和守護線程”吧!

守護線程是一種特殊的線程,在后臺默默地完成一些系統性的服務,比如垃圾回收線程、JIT線程都是守護線程。與之對應的是用戶線程,用戶線程可以理解為是系統的工作線程,它會完成這個程序需要完成的業務操作。如果用戶線程全部結束了,意味著程序需要完成的業務操作已經結束了,系統可以退出了。所以當系統只剩下守護進程的時候,java虛擬機會自動退出。

java線程分為用戶線程和守護線程,線程的daemon屬性為true表示是守護線程,false表示是用戶線程。

下面我們來看一下守護線程的一些特性。

程序只有守護線程時,系統會自動退出

package com.itsoku.chat03;	
/**	
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!	
 */	
public class Demo1 {	
    public static class T1 extends Thread {	
        public T1(String name) {	
            super(name);	
        }	
        @Override	
        public void run() {	
            System.out.println(this.getName() + "開始執行," + (this.isDaemon() ? "我是守護線程" : "我是用戶線程"));	
            while (true) ;	
        }	
    }	
    public static void main(String[] args) {	
        T1 t1 = new T1("子線程1");	
        t1.start();	
        System.out.println("主線程結束");	
    }	
}

運行上面代碼,結果如下:

怎么理解java高并發的用戶線程和守護線程

可以看到主線程已經結束了,但是程序無法退出,原因:子線程1是用戶線程,內部有個死循環,一直處于運行狀態,無法結束。

再看下面的代碼:

package com.itsoku.chat03;	
/**	
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!	
 */	
public class Demo2 {	
    public static class T1 extends Thread {	
        public T1(String name) {	
            super(name);	
        }	
        @Override	
        public void run() {	
            System.out.println(this.getName() + "開始執行," + (this.isDaemon() ? "我是守護線程" : "我是用戶線程"));	
            while (true) ;	
        }	
    }	
    public static void main(String[] args) {	
        T1 t1 = new T1("子線程1");	
        t1.setDaemon(true);	
        t1.start();	
        System.out.println("主線程結束");	
    }	
}

運行結果:

怎么理解java高并發的用戶線程和守護線程

程序可以正常結束了,代碼中通過 t1.setDaemon(true); 將t1線程設置為守護線程,main方法所在的主線程執行完畢之后,程序就退出了。

結論:當程序中所有的用戶線程執行完畢之后,不管守護線程是否結束,系統都會自動退出。

設置守護線程,需要在start()方法之前進行

package com.itsoku.chat03;	
import java.util.concurrent.TimeUnit;	
/**	
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!	
 */	
public class Demo3 {	
    public static void main(String[] args) {	
        Thread t1 = new Thread() {	
            @Override	
            public void run() {	
                try {	
                    TimeUnit.SECONDS.sleep(10);	
                } catch (InterruptedException e) {	
                    e.printStackTrace();	
                }	
            }	
        };	
        t1.start();	
        t1.setDaemon(true);	
    }	
}

t1.setDaemon(true);是在t1的start()方法之后執行的,執行會報異常,運行結果如下:

怎么理解java高并發的用戶線程和守護線程

線程daemon的默認值

我們看一下創建線程源碼,位于Thread類的init()方法中:

Thread parent = currentThread();	
this.daemon = parent.isDaemon();

dameon的默認值為為父線程的daemon,也就是說,父線程如果為用戶線程,子線程默認也是用戶現場,父線程如果是守護線程,子線程默認也是守護線程。

示例代碼:

package com.itsoku.chat03;	
import java.util.concurrent.TimeUnit;	
/**	
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!	
 */	
public class Demo4 {	
    public static class T1 extends Thread {	
        public T1(String name) {	
            super(name);	
        }	
        @Override	
        public void run() {	
            System.out.println(this.getName() + ".daemon:" + this.isDaemon());	
        }	
    }	
    public static void main(String[] args) throws InterruptedException {	
        System.out.println(Thread.currentThread().getName() + ".daemon:" + Thread.currentThread().isDaemon());	
        T1 t1 = new T1("t1");	
        t1.start();	
        Thread t2 = new Thread() {	
            @Override	
            public void run() {	
                System.out.println(this.getName() + ".daemon:" + this.isDaemon());	
                T1 t3 = new T1("t3");	
                t3.start();	
            }	
        };	
        t2.setName("t2");	
        t2.setDaemon(true);	
        t2.start();	
        TimeUnit.SECONDS.sleep(2);	
    }	
}

運行代碼,輸出:

main.daemon:false
t1.daemon:false
t2.daemon:true
t3.daemon:true

t1是由主線程(main方法所在的線程)創建的,main線程是t1的父線程,所以t1.daemon為false,說明t1是用戶線程。

t2線程調用了 setDaemon(true);將其設為守護線程,t3是由t2創建的,所以t3默認線程類型和t2一樣,t2.daemon為true。

感謝各位的閱讀,以上就是“怎么理解java高并發的用戶線程和守護線程”的內容了,經過本文的學習后,相信大家對怎么理解java高并發的用戶線程和守護線程這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新闻| 昌平区| 齐齐哈尔市| 道真| 黄山市| 将乐县| 毕节市| 元氏县| 蒙自县| 北碚区| 昌都县| 邵阳县| 静安区| 江陵县| 刚察县| 瓦房店市| 梨树县| 抚宁县| 宁都县| 疏附县| 杭州市| 信阳市| 定日县| 泽州县| 九江县| 石屏县| 台安县| 溧水县| 舒城县| 八宿县| 且末县| 额敏县| 冷水江市| 阳谷县| 临邑县| 大连市| 高雄县| 汨罗市| 准格尔旗| 噶尔县| 秦皇岛市|