并發(fā)系列之ThreadGroup

首爾國立大學(xué)(韓國)校訓(xùn):“真理是我的光明材泄。”


生活的前方不管有多少荊棘吨岭,我都隨身攜帶著鐮刀拉宗,砥礪前行;烈日高陽辣辫,打一罐雞血旦事,開啟一天的新生活!
前面幾篇聊了很多線程的基礎(chǔ)知識急灭,今天講下線程的家族式管理ThreadGroup族檬,類似中國的宗族制,每個(gè)人都有隸屬的一脈化戳,絕不可能是游離的单料;同樣,jvm管理線程也采用了這種思想点楼,每個(gè)線程也絕不會是游離的扫尖,都有隸屬的ThreadGroup÷永可能大家在工作中沒有注意到它的存在换怖,但在某些場景下還是很有用途的。下面就從線程組的基本概念/管理結(jié)構(gòu)/使用場景簡單聊下:

一 概述線程組

線程組管理線程是一種組織式地管理蟀瞧,類似與公司的組織架構(gòu)管理沉颂,要注意與線程池管理線程進(jìn)行區(qū)分;它是按一定層級結(jié)構(gòu)管理線程或線程組對象悦污,線程和線程組構(gòu)成的結(jié)構(gòu)是樹形铸屉,可以通過遞歸遍歷的方式獲取整個(gè)線程樹。線程組有幾個(gè)重要特性切端,如下:
1/自動(dòng)歸屬彻坛,即線程或線程組具有默認(rèn)機(jī)制,通俗地說,創(chuàng)建一個(gè)線程或線程組昌屉,它必有自己的所屬的線程組钙蒙,每個(gè)線程都不可能是游離的,這可以通過查看new Thread()和new ThreadGroup()的源碼查閱便知间驮。
2/多級關(guān)聯(lián)躬厌,父對象中有子對象,子對象可創(chuàng)建子對象竞帽,子子孫孫無窮盡也烤咧,這是基于jdk提供的線程樹結(jié)構(gòu),但在實(shí)際開發(fā)中抢呆,都是以簡單易讀地方式管理線程煮嫌,所以推薦一級關(guān)聯(lián)。
3/一級關(guān)聯(lián)抱虐,父對象中有子對象昌阿,但不能創(chuàng)建孫對象,即樹形結(jié)構(gòu)只有兩層恳邀,這在實(shí)際工作中大部分場景已經(jīng)夠用懦冰,組織結(jié)構(gòu)越簡單,自然管理也就越簡單谣沸,故在工作中推薦使用刷钢。
demo世界不孤單,請閱:

/**
 * @author 阿倫故事
 * @Description:描述線程組的基本屬性
 * */
@Slf4j
public class GroupBasic {

    public static void main(String[] args) {
        GroupBasic groupBasic = new GroupBasic();
        //auto
        groupBasic.auto();
        //one level
        groupBasic.oneLevel();
        //multi level
        groupBasic.multiLevel();
    }
    /**
     * 自動(dòng)歸屬
     * */
    public void auto(){
        Thread current = Thread.currentThread();
        Thread thread = new Thread(()->{
            log.info("---run---");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread.start();
        log.info("--current thread name:"+current.getName() + "乳附,線程組:"+current.getThreadGroup().getName());
        log.info("--new thread name:"+thread.getName() + "内地,線程組:"+thread.getThreadGroup().getName());
    }
    /**
     * 一級關(guān)聯(lián)
     * */
    public void oneLevel(){
        ThreadGroup group = new ThreadGroup("一級線程組");
        Thread t1 = new Thread(()->{
            log.info("---t1 run---");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread t2 = new Thread(()->{
            log.info("---t2 run---");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread one = new Thread(group, t1);
        Thread two = new Thread(group, t2);
        one.start();
        two.start();
        log.info("--ThreadGroup name:"+group.getName() + ",存活線程個(gè)數(shù):"+group.activeCount());
    }
    /**
     * 多級關(guān)聯(lián)
     * */
    public void multiLevel(){
        ThreadGroup group = new ThreadGroup("一級線程組");
        ThreadGroup group1 = new ThreadGroup(group,"二級線程組A");
        ThreadGroup group2 = new ThreadGroup(group,"二級線程組B");
        Thread t1 = new Thread(()->{
            log.info("---t1 run---");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread t2 = new Thread(()->{
            log.info("---t2 run---");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread t3 = new Thread(()->{
            log.info("---t3 run---");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        Thread one = new Thread(group, t1);
        Thread two = new Thread(group1, t2);
        Thread three = new Thread(group2, t3);
        one.start();
        two.start();
        three.start();
        log.info("--一級線程組 name:"+group.getName() + "赋除,存活線程個(gè)數(shù):"+group.activeCount()
                +"阱缓,子線程組個(gè)數(shù):"+group.activeGroupCount());
        log.info("--二級線程組A name:"+group1.getName() + ",存活線程個(gè)數(shù):"+group1.activeCount()
                +"举农,子線程組個(gè)數(shù):"+group1.activeGroupCount());
        log.info("--二級線程組B name:"+group2.getName() + "荆针,存活線程個(gè)數(shù):"+group2.activeCount()
                +",子線程組個(gè)數(shù):"+group2.activeGroupCount());
    }
}

二 線程批管理

線程組在實(shí)戰(zhàn)中有什么用呢颁糟,主要用對一批線程進(jìn)行管理航背,如中斷(interrupt)/暫停(suspend)/恢復(fù)(resume)/終止(stop)等操作,這里注意下ThreadGroup的destroy方法棱貌,是清除掉這個(gè)線程組及其所有子線程組玖媚,但要注意這里的所有線程組包括子線程組必須是空的,也就是說線程組里的線程都銷亡了键畴,否則會拋出異常最盅。
這里主要講下實(shí)戰(zhàn)中的使用場景:
1/在單個(gè)應(yīng)用中,使用多線程開發(fā)起惕,必然聲明線程池管理線程涡贱,建議根據(jù)業(yè)務(wù)模塊聲明相應(yīng)的線程組來管理,便于針對某一業(yè)務(wù)模塊的線程做統(tǒng)一處理惹想;
2/在任務(wù)調(diào)度模塊中问词,聲明多個(gè)耗時(shí)任務(wù)執(zhí)行數(shù)據(jù)處理,如果定時(shí)任務(wù)長時(shí)間未執(zhí)行完畢嘀粱,可能是由于執(zhí)行過程中出現(xiàn)了異常等激挪,這時(shí)需要把這類任務(wù)終止,就可以利用線程組把一類線程中斷掉锋叨。
demo世界不孤單垄分,請閱:

/**
 * @author 阿倫故事
 * @Description:描述線程組批處理
 * */
@Slf4j
public class GroupBatch {
    public static void main(String[] args) throws InterruptedException{
        GroupBatch groupBatch = new GroupBatch();
        groupBatch.batchTest();
    }
    /**
     * 線程組下的線程任務(wù)執(zhí)行異常,需要全部終止
     * */
    public void batchTest() throws InterruptedException{
        ThreadGroup group = new ThreadGroup("批處理線程組");
        for (int i = 0; i <5 ; i++) {
            new Thread(group, new SubTask(),"subtask-0"+i).start();
        }
        Thread.sleep(5000);
        log.info("--all SubTask 阻塞娃磺,需終止--");
        group.interrupt();//中斷線程組下的所有線程任務(wù)
        Thread.sleep(2000);
        log.info("--stop the world--");
    }
    static class SubTask implements Runnable{
        @Override
        public void run() {
            log.info("--subTask thread name:"+ Thread.currentThread().getName() + "薄湿,begin run");
            while(!Thread.currentThread().isInterrupted()){ };
            log.info("--subTask thread name:"+ Thread.currentThread().getName() + ",end run");
        }
    }
}

特此聲明:
分享文章有完整的知識架構(gòu)圖偷卧,將從以下幾個(gè)方面系統(tǒng)展開:
1 基礎(chǔ)(Linux/Spring boot/并發(fā))
2 性能調(diào)優(yōu)(jvm/tomcat/mysql)
3 高并發(fā)分布式
4 微服務(wù)體系
如果您覺得文章不錯(cuò)豺瘤,請關(guān)注阿倫故事,您的支持是我堅(jiān)持的莫大動(dòng)力听诸,在此受小弟一拜坐求!


每篇福利:

評論區(qū)打出車型.jpg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市晌梨,隨后出現(xiàn)的幾起案子桥嗤,更是在濱河造成了極大的恐慌,老刑警劉巖仔蝌,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砸逊,死亡現(xiàn)場離奇詭異,居然都是意外死亡掌逛,警方通過查閱死者的電腦和手機(jī)师逸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豆混,“玉大人篓像,你說我怎么就攤上這事∶笏牛” “怎么了员辩?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸵鸥。 經(jīng)常有香客問我奠滑,道長丹皱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任宋税,我火速辦了婚禮摊崭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘杰赛。我一直安慰自己呢簸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布乏屯。 她就那樣靜靜地躺著根时,像睡著了一般。 火紅的嫁衣襯著肌膚如雪辰晕。 梳的紋絲不亂的頭發(fā)上蛤迎,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機(jī)與錄音含友,去河邊找鬼忘苛。 笑死,一個(gè)胖子當(dāng)著我的面吹牛唱较,可吹牛的內(nèi)容都是我干的扎唾。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼南缓,長吁一口氣:“原來是場噩夢啊……” “哼胸遇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汉形,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤纸镊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后概疆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逗威,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年岔冀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凯旭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,569評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡使套,死狀恐怖罐呼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情侦高,我是刑警寧澤嫉柴,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站奉呛,受9級特大地震影響计螺,放射性物質(zhì)發(fā)生泄漏夯尽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一登馒、第九天 我趴在偏房一處隱蔽的房頂上張望匙握。 院中可真熱鬧,春花似錦谊娇、人聲如沸肺孤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至小渊,卻和暖如春法褥,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背酬屉。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工半等, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人呐萨。 一個(gè)月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓杀饵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親谬擦。 傳聞我的和親對象是個(gè)殘疾皇子切距,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,090評論 1 32
  • 不足的地方請大家多多指正,如有其它沒有想到的常問面試題請大家多多評論惨远,一起成長谜悟,感謝!~ String可以被繼承嗎...
    啟示錄是真的閱讀 2,924評論 3 3
  • 線程組介紹 線程組的構(gòu)造 ThreadGroup方法介紹查看線程組信息終止線程組中的所有線程 總結(jié) Links作者...
    西召閱讀 595評論 0 0
  • 所有知識點(diǎn)已整理成app app下載地址 J2EE 部分: 1.Switch能否用string做參數(shù)? 在 Jav...
    侯蛋蛋_閱讀 2,412評論 1 4
  • 既然要談原則北秽,那么首先我們要弄清楚什么是原則葡幸。什么是原則呢?原則的定義是:說話或行事所依據(jù)的法則或標(biāo)準(zhǔn)贺氓。 人的任何...
    ibenlai閱讀 798評論 0 2