啟動(dòng)一個(gè)最簡單的Java main程序時(shí)钧忽,有多少個(gè)線程被創(chuàng)建

事情的全部起因來自于這樣一個(gè)程序

public class VolatileTest {
    public static volatile int race = 0;

    public static void increase(){
        race++;
    }

    private static final int THREADS_COUNT = 10;

    public static void main(String[] args) {

        Thread[] threads = new Thread[THREADS_COUNT];

        for (int i = 0;i < THREADS_COUNT;i++){
            threads[i] = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i = 0;i < 10;i++){
                        increase();
                    }
                }
            });
            threads[i].start();
        }

        while (Thread.activeCount() > 1){
            System.out.println(Thread.activeCount());
            Thread.yield();
        }
        System.out.println(race);
    }
}

這是一個(gè)簡單的多線程下的計(jì)數(shù)器油够,用于說明volatile修飾的變量并不能完全解決多線程并發(fā)問題边翼,體現(xiàn)在這段代碼中就是最后打印的結(jié)果有可能<100须眷。

這篇博文的主題不是討論volatile關(guān)鍵字的用法竖瘾,而是你如果在linux下跑這段程序,會(huì)卡在死循環(huán)了出不來花颗,各種百度捕传,google,總算找到了問題扩劝,我們先來看一看庸论,簡單啟動(dòng)一個(gè)main程序時(shí),有多少個(gè)線程被創(chuàng)建呢棒呛?


        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();

        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false,false);

        for (ThreadInfo info : threadInfos
             ) {
            System.out.println("[" + info.getThreadId() + "]" + info.getThreadName());
        }

        System.out.println(Thread.activeCount());

最后打印結(jié)果如下

main線程.png

好聂示,我們分別來看看這幾個(gè)線程都是干嘛用的,這部分內(nèi)容主要來自
http://ifeve.com/jvm-thread/条霜,可以去這個(gè)地址查看更多線程的信息

Attach Listener

Attach Listener線程是負(fù)責(zé)接收到外部的命令催什,而對(duì)該命令進(jìn)行執(zhí)行的并且吧結(jié)果返回給發(fā)送者。通常我們會(huì)用一些命令去要求jvm給我們一些反 饋信息宰睡,如:java -version、jmap气筋、jstack等等拆内。如果該線程在jvm啟動(dòng)的時(shí)候沒有初始化,那么宠默,則會(huì)在用戶第一次執(zhí)行jvm命令時(shí)麸恍,得到啟動(dòng)。

Signal Dispatcher

前面我們提到第一個(gè)Attach Listener線程的職責(zé)是接收外部jvm命令搀矫,當(dāng)命令接收成功后抹沪,會(huì)交給signal dispather線程去進(jìn)行分發(fā)到各個(gè)不同的模塊處理命令,并且返回處理結(jié)果瓤球。signal dispather線程也是在第一次接收外部jvm命令時(shí)融欧,進(jìn)行初始化工作。

Finalizer

這個(gè)線程也是在main線程之后創(chuàng)建的卦羡,其優(yōu)先級(jí)為10噪馏,主要用于在垃圾收集前麦到,調(diào)用對(duì)象的finalize()方法;關(guān)于Finalizer線程的幾點(diǎn):

1. 只有當(dāng)開始一輪垃圾收集時(shí)欠肾,才會(huì)開始調(diào)用finalize()方法瓶颠;因此并不是所有對(duì)象的finalize()方法都會(huì)被執(zhí)行;
  2. 該線程也是daemon線程刺桃,因此如果虛擬機(jī)中沒有其他非daemon線程粹淋,不管該線程有沒有執(zhí)行完finalize()方法,JVM也會(huì)退出瑟慈;
  3. JVM在垃圾收集時(shí)會(huì)將失去引用的對(duì)象包裝成Finalizer對(duì)象(Reference的實(shí)現(xiàn))桃移,并放入ReferenceQueue,由Finalizer線程來處理封豪;最后將該Finalizer對(duì)象的引用置為null谴轮,由垃圾收集器來回收;
  4. JVM為什么要單獨(dú)用一個(gè)線程來執(zhí)行finalize()方法呢吹埠?如果JVM的垃圾收集線程自己來做第步,很有可能由于在finalize()方法中誤操作導(dǎo)致GC線程停止或不可控,這對(duì)GC線程來說是一種災(zāi)難缘琅;

Reference Handler

VM在創(chuàng)建main線程后就創(chuàng)建Reference Handler線程粘都,其優(yōu)先級(jí)最高,為10刷袍,它主要用于處理引用對(duì)象本身(軟引用翩隧、弱引用、虛引用)的垃圾回收問題呻纹。

Monitor Ctrl-Break

這個(gè)線程我也不是很明白是干什么用的堆生,oracle官網(wǎng)有詳細(xì)信息,大家可以去看看
詳細(xì)鏈接

那問題來了雷酪,在linux下雖然創(chuàng)建了5個(gè)線程淑仆,但是當(dāng)前活動(dòng)線程只有兩個(gè),main和Monitor Ctrl-Break哥力,這就導(dǎo)致了蔗怠,我們在等待所有子線程結(jié)束后的那句判斷代碼應(yīng)該是>2而不是>1!!!

while (Thread.activeCount() > 2){
            System.out.println(Thread.activeCount());
            Thread.yield();
        }

結(jié)論

windows下這個(gè)Monitor Ctrl-Break是不算在活動(dòng)線程的,所以這樣大于1是可以執(zhí)行的吩跋,但是linux下應(yīng)該是 大于2

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末寞射,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锌钮,更是在濱河造成了極大的恐慌桥温,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轧粟,死亡現(xiàn)場離奇詭異策治,居然都是意外死亡脓魏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門通惫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茂翔,“玉大人,你說我怎么就攤上這事履腋∩毫牵” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵遵湖,是天一觀的道長悔政。 經(jīng)常有香客問我,道長延旧,這世上最難降的妖魔是什么谋国? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮迁沫,結(jié)果婚禮上芦瘾,老公的妹妹穿的比我還像新娘。我一直安慰自己集畅,他們只是感情好近弟,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著挺智,像睡著了一般祷愉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赦颇,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天二鳄,我揣著相機(jī)與錄音,去河邊找鬼媒怯。 笑死泥从,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的沪摄。 我是一名探鬼主播,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼纱烘,長吁一口氣:“原來是場噩夢啊……” “哼杨拐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起擂啥,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤哄陶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后哺壶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屋吨,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜒谤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了至扰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鳍徽。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖敢课,靈堂內(nèi)的尸體忽然破棺而出阶祭,到底是詐尸還是另有隱情,我是刑警寧澤直秆,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布濒募,位于F島的核電站,受9級(jí)特大地震影響圾结,放射性物質(zhì)發(fā)生泄漏瑰剃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一筝野、第九天 我趴在偏房一處隱蔽的房頂上張望晌姚。 院中可真熱鬧,春花似錦遗座、人聲如沸舀凛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽猛遍。三九已至,卻和暖如春号坡,著一層夾襖步出監(jiān)牢的瞬間懊烤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工宽堆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腌紧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓畜隶,卻偏偏與公主長得像壁肋,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子籽慢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

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

  • 姓名:郭金 學(xué)號(hào):17101223407 【嵌牛導(dǎo)讀】:之前看到一個(gè)用jstack查看死鎖的例子浸遗。總結(jié)了一下:js...
    寶寶啦啦啦閱讀 795評(píng)論 0 0
  • 從三月份找實(shí)習(xí)到現(xiàn)在箱亿,面了一些公司跛锌,掛了不少,但最終還是拿到小米届惋、百度髓帽、阿里菠赚、京東、新浪郑藏、CVTE衡查、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,278評(píng)論 11 349
  • 1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供...
    簡欲明心閱讀 89,576評(píng)論 17 311
  • 原文閱讀 前言 這段時(shí)間懈怠了译秦,罪過峡捡! 最近看到有同事也開始用上了微信公眾號(hào)寫博客了,挺好的~給他們點(diǎn)贊筑悴,這博客我...
    碼農(nóng)戲碼閱讀 5,994評(píng)論 2 31
  • “羽扇綸巾笑談間们拙,千軍萬馬我無懈「罅撸” 你高居南陽砚婆,行吟隴畝,未出草廬卻知天下三分突勇。當(dāng)年装盯,白梅初放,劉備踏著白雪甲馋,三...
    葉小一silence閱讀 372評(píng)論 0 0