Thread (core java)

創(chuàng)建線程

建議不要通過構(gòu)建Thread子類對(duì)象捐凭,并調(diào)用start方法洒嗤。應(yīng)該從運(yùn)行機(jī)制上減少需要并行運(yùn)行的任務(wù)數(shù)量改艇。如果有很多任務(wù)秀又,要為每個(gè)任務(wù)創(chuàng)建一個(gè)獨(dú)立的線程付出的代價(jià)太大媒惕,可以使用線程池來解決這個(gè)問題帝簇。(參考14.9)

java.lang.Thread

  1. Thread(Runnable target) 構(gòu)造一個(gè)新線程用于調(diào)用給定target的run方法徘郭。
  2. void start() 啟動(dòng)此線程靠益,將引發(fā)調(diào)用run()方法,這個(gè)方法會(huì)立即返回残揉,并且新線程將并行運(yùn)行胧后。
  3. void run() 調(diào)用關(guān)聯(lián)Runnable的run方法。

java.lang.Runnable

  1. void run() 必須覆蓋這個(gè)方法抱环,并在這個(gè)方法中提供所需要執(zhí)行的任務(wù)指令壳快。

中斷線程

早期java使用stop()方法可以強(qiáng)制線程中止,現(xiàn)在已經(jīng)被棄用镇草;
interrupt() 方法可以用來請(qǐng)求中止線程眶痰。但是如果線程被阻塞,就無法檢測(cè)中斷狀態(tài)陶夜。這是產(chǎn)生InterruptedException異常的地方凛驮,當(dāng)在一個(gè)被阻塞的線程(調(diào)用sleep或wait)上調(diào)用interrupt方法時(shí),阻塞調(diào)用將會(huì)被InterruptedException異常中斷条辟,這里指會(huì)進(jìn)入catch代碼塊執(zhí)行(存在不能被中斷的阻塞I/O調(diào)用黔夭,應(yīng)該考慮選擇可中斷的調(diào)用。細(xì)節(jié)參考卷二 第一章和第三章)
java.lang.Thread

  1. void interrupt() 向線程發(fā)送中斷請(qǐng)求羽嫡,線程的中斷狀態(tài)將被設(shè)置為true.
    如果目前線程被一個(gè)sleep調(diào)用阻塞本姥,那么InterruptedException異常被拋出,此外中斷狀態(tài)將被清除
  2. static boolean interrupted() 測(cè)試正在執(zhí)行這一方法的線程是否被中斷杭棵,注意這是一個(gè)靜態(tài)方法婚惫,調(diào)用會(huì)產(chǎn)生副作用,它將當(dāng)前線程的中斷狀態(tài)重置為false.(線程的中斷狀態(tài)被清除)
  3. boolean isInterrupted() 測(cè)試線程是否終止魂爪,不像靜態(tài)的中斷方法先舷,這一調(diào)用不改變線程的中斷狀態(tài)。
  4. static Thread currentThread() 返回代表當(dāng)前執(zhí)行線程的Thread對(duì)象滓侍。
  5. static void sleep(long millis) 休眠給定的毫秒數(shù)

void interrupt() 中斷此線程蒋川。(谷歌翻譯)
線程用一個(gè)變量來標(biāo)志中斷狀態(tài),private volatile Interruptible blocker;
除非當(dāng)前線程正在中斷自身(始終允許)撩笆,否則將調(diào)用此線程的checkAccess方法捺球,這可能導(dǎo)致拋出SecurityException。
如果在調(diào)用Object類的wait()夕冲,wait(long)或wait(long氮兵,int)方法或者join(),join(long)歹鱼,join(long泣栈,int)的方法中阻塞了這個(gè)線程,sleep(long)或sleep(long,int)南片,這個(gè)類的方法篙悯,然后它的中斷狀態(tài)將被清除,它將收到InterruptedException铃绒。
如果此線程在可中斷通道上的I / O操作中被阻塞,則通道將被關(guān)閉螺捐,線程的中斷狀態(tài)將被設(shè)置颠悬,并且線程將收到ClosedByInterruptException。
如果此線程在Selector中被阻塞定血,則線程的中斷狀態(tài)將被設(shè)置赔癌,并且它將立即從選擇操作返回,可能具有非零值澜沟,就像調(diào)用選擇器的喚醒方法一樣灾票。
如果以前的條件都不成立,則將設(shè)置該線程的中斷狀態(tài)茫虽。
中斷不活動(dòng)的線程不會(huì)產(chǎn)生任何影響刊苍。

public class TestRun implements Runnable {
    private boolean flag = true;

    @Override
    public void run() {
        try {
            while (!Thread.currentThread().isInterrupted() && flag) {
                // do more work
                Thread.currentThread().sleep(1000);
            }
        }
        catch (InterruptedException e) {
            // thread was interrupted during sleep or wait
            
        }
        finally {
            //cleanup,if required
        }
        //exiting the run method terminates the thread
    }
    
    void mySubTask() {
        try {
            Thread.currentThread().sleep(1000);
        }
        catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    void mySubTask2() throws InterruptedException {
        Thread.currentThread().sleep(1000);
    }
}

線程狀態(tài)

  1. 新建 New
    new Thread(r)/new MyThread()
  2. 可運(yùn)行 Runnable
    thread.start()
    (搶占式調(diào)度系統(tǒng);協(xié)作式調(diào)度系統(tǒng)中,一個(gè)線程只有在調(diào)用yield方法或者被阻塞或等待時(shí),線程才會(huì)失去控制權(quán))
    任何時(shí)刻濒析,一個(gè)可運(yùn)行的線程可能正在運(yùn)行正什,也可能沒有運(yùn)行
  3. 被阻塞 Blocked
    一個(gè)線程試圖獲取一個(gè)內(nèi)部對(duì)象鎖,而該鎖被其它對(duì)象持有号杏,則線程進(jìn)入阻塞狀態(tài)婴氮。
  4. 等待 Waiting/ 計(jì)時(shí)等待 Timed waiting
    Thread.sleep
    Object.wait
    Thread.join
    Lock.tryLock
    Condition.await
  5. 被中止 Terminated
    因?yàn)閞un方法正常退出而自然死亡
    因?yàn)橐粋€(gè)沒有捕獲的異常中止了run方法而意外死亡
    stop方法已過時(shí),不要在代碼中使用
  6. 相關(guān)的API
    java.lang.Thread

6.1void join():等待中止指定的線程即等待指定的線程終止后再繼續(xù)當(dāng)前線程
6.2void join(long millis):等待指定的線程死亡盾致,或者經(jīng)過指定的毫秒數(shù)
6.3Thread.State getState():獲取線程的狀態(tài)
6.4void stop():停止線程主经,已過時(shí)
6.5void suspend:暫停線程執(zhí)行,已過時(shí)
6.6void resume:調(diào)用suspend之后調(diào)用庭惜,已過時(shí)

線程屬性

  1. 優(yōu)先級(jí)
    高優(yōu)先級(jí)只代表線程優(yōu)先獲取時(shí)間片的可能性比較大罩驻,不是必然
  2. API
    java.lang.Thread

2.1void setPriority(int newPriority):設(shè)置優(yōu)先級(jí),必須在Thread.MIN_PRIORITY與Thread.MAX_PRIORITY之間蜈块,一般使用Thread.NORM_PRIORITY優(yōu)先級(jí)鉴腻。
2.2static int MIN_PRIORITY:線程最小優(yōu)先級(jí)1.
2.3static int MAX_PRIORITY:線程最大優(yōu)先級(jí)10.
2.4static int NORM_PRIORITY:線程默認(rèn)優(yōu)先級(jí)5.
2.5static void yield():導(dǎo)致當(dāng)前執(zhí)行線程處于讓步狀態(tài),如果有其他可運(yùn)行的線程具有至少與此線程同樣高的優(yōu)先級(jí)百揭,那么這些線程接下來會(huì)被調(diào)度爽哎。注意,這是一個(gè)靜態(tài)方法器一。

3.守護(hù)線程/API
3.守護(hù)線程優(yōu)先級(jí)很低课锌,當(dāng)同一應(yīng)用程序中沒有其他線程在運(yùn)行的時(shí)候,守護(hù)線程才運(yùn)行。當(dāng)守護(hù)線程是程序中唯一運(yùn)行的線程時(shí)渺贤,守護(hù)線程執(zhí)行結(jié)束后雏胃,JVM也就結(jié)束了這個(gè)程序。
3.2守護(hù)線程的作用:通常作為同一程序中普通線程的服務(wù)提供者志鞍,它們通常是無限循環(huán)的瞭亮,以等待服務(wù)請(qǐng)求或者執(zhí)行線程的任務(wù)。此外我們不太可能知道守護(hù)線程什么時(shí)候能夠獲取CPU時(shí)鐘固棚,并且沒有其它線程運(yùn)行的時(shí)候统翩,守護(hù)線程隨時(shí)可能結(jié)束。一個(gè)典型的守護(hù)線程是Java的垃圾回收器此洲。
java.lang.Thread

3.3void setDaemon(boolean isDaemon):標(biāo)識(shí)該線程為守護(hù)線程或用戶線程厂汗。這一方法必須在線程啟動(dòng)之前調(diào)用

4未捕獲異常處理器
4.1未捕獲異常處理器介紹
線程的run方法不能拋出任何被檢測(cè)的異常,但是呜师,不被檢測(cè)的異常會(huì)導(dǎo)致線程終止娶桦。在這種情況下,線程就死亡了汁汗。就作線程死亡之前衷畦,異
常被傳遞到一個(gè)用于未捕獲異常的處理器。
該處理器必須屬于一個(gè)實(shí)現(xiàn)Thread.UncaughtExceptionHandler接口的類碰酝。
這個(gè)接口只有一個(gè)方法霎匈。
void uncauqhtException(Thread t, Throwable e)
可以用 setUncaughtExceptionHandler方法為任何線程安裝一個(gè)處理器。也可以用 Thread類的靜態(tài)方法setDefaultUncaughtExceptionHandlcr為所有線程安裝一個(gè)默認(rèn)的處理器送爸。如果不安裝默認(rèn)的處理器铛嘱,默認(rèn)的處理器為空。但是袭厂,如果沒有設(shè)置UncaughtExceptionHandler墨吓,那么默認(rèn)將會(huì)把異常棧信息輸出到System.err,此時(shí)的處理器就足該線程的ThreadGroup對(duì)象纹磺。

線程組是一個(gè)可以統(tǒng)一管理的線程集合帖烘。默認(rèn)情況下,創(chuàng)建的所有線程屬于相同的線程組橄杨,但是秘症,也可能會(huì)建立其他的組。現(xiàn)在引入了更好的特性用于線程集合的操作式矫,所以建議不要在自己的程序中使用線程組乡摹。
ThreadGroup 類實(shí)現(xiàn) Thread.UncaughtException 接口。它的uncaughtException方法如下:

 /**
     * Called by the Java Virtual Machine when a thread in this
     * thread group stops because of an uncaught exception, and the thread
     * does not have a specific {@link Thread.UncaughtExceptionHandler}
     * installed.
     * <p>
     * The <code>uncaughtException</code> method of
     * <code>ThreadGroup</code> does the following:
     * <ul>
     * <li>If this thread group has a parent thread group, the
     *     <code>uncaughtException</code> method of that parent is called
     *     with the same two arguments.
     * <li>Otherwise, this method checks to see if there is a
     *     {@linkplain Thread#getDefaultUncaughtExceptionHandler default
     *     uncaught exception handler} installed, and if so, its
     *     <code>uncaughtException</code> method is called with the same
     *     two arguments.
     * <li>Otherwise, this method determines if the <code>Throwable</code>
     *     argument is an instance of {@link ThreadDeath}. If so, nothing
     *     special is done. Otherwise, a message containing the
     *     thread's name, as returned from the thread's {@link
     *     Thread#getName getName} method, and a stack backtrace,
     *     using the <code>Throwable</code>'s {@link
     *     Throwable#printStackTrace printStackTrace} method, is
     *     printed to the {@linkplain System#err standard error stream}.
     * </ul>
     * <p>
     * Applications can override this method in subclasses of
     * <code>ThreadGroup</code> to provide alternative handling of
     * uncaught exceptions.
     *
     * @param   t   the thread that is about to exit.
     * @param   e   the uncaught exception.
     * @since   JDK1.0
     */
    public void uncaughtException(Thread t, Throwable e) {
        if (parent != null) {
            parent.uncaughtException(t, e);
        } else {
            Thread.UncaughtExceptionHandler ueh =
                Thread.getDefaultUncaughtExceptionHandler();
            if (ueh != null) {
                ueh.uncaughtException(t, e);
            } else if (!(e instanceof ThreadDeath)) {
                System.err.print("Exception in thread \""
                                 + t.getName() + "\" ");
                e.printStackTrace(System.err);
            }
        }
    }

4.2相關(guān)API
java.lang.Thread
4.2.1 public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)
4.2.2 public static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler()
4.3.3 public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
4.4.4 public Thread.UncaughtExceptionHandler getUncaughtExceptionHandler()

java.lang.Thread.UncaughtExceptionHandler
4.2.5 void uncaughtException(Thread t,Throwable e)當(dāng)給定線程因給定的未捕獲異常而終止時(shí)采转,調(diào)用該方法聪廉。 Java 虛擬機(jī)將忽略該方法拋出的任何異常瞬痘。

java.lang.ThreadGroup
4.2.6 public void uncaughtException(Thread t,Throwable e)當(dāng)此線程組中的線程因?yàn)橐粋€(gè)未捕獲的異常而停止,并且線程沒有安裝特定 Thread.UncaughtExceptionHandler 時(shí)板熊,由 Java Virtual Machine 調(diào)用此方法框全。

ThreadGroup 的 uncaughtException 方法執(zhí)行以下操作:
1.如果此線程組有一個(gè)父線程組,那么調(diào)用此父線程組的 uncaughtException 方法時(shí)帶有兩個(gè)相同的參數(shù)干签。
2.否則津辩,此方法將查看是否安裝了默認(rèn)的未捕獲異常處理程序,如果是容劳,則在調(diào)用其 uncaughtException 方法時(shí)帶有兩個(gè)相同的參數(shù)丹泉。
3.否則,此方法將確認(rèn) Throwable 參數(shù)是否為一個(gè) ThreadDeath 實(shí)例鸭蛙。如果是,則不會(huì)做任何特殊的操作筋岛。否則娶视,在從線程的 getName 方法返回時(shí),會(huì)使用 Throwable 的 printStackTrace 方法睁宰,將包含線程名稱的消息和堆棧跟蹤信息輸出到標(biāo)準(zhǔn)錯(cuò)誤流肪获。
應(yīng)用程序可以重寫 ThreadGroup 的子類中的方法,以提供處理未捕獲異常的替代辦法柒傻。

線程同步

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末孝赫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子红符,更是在濱河造成了極大的恐慌青柄,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件预侯,死亡現(xiàn)場(chǎng)離奇詭異致开,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)萎馅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門双戳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人糜芳,你說我怎么就攤上這事飒货。” “怎么了峭竣?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵塘辅,是天一觀的道長。 經(jīng)常有香客問我邪驮,道長莫辨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮沮榜,結(jié)果婚禮上盘榨,老公的妹妹穿的比我還像新娘。我一直安慰自己蟆融,他們只是感情好草巡,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著型酥,像睡著了一般山憨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弥喉,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天郁竟,我揣著相機(jī)與錄音,去河邊找鬼由境。 笑死棚亩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的虏杰。 我是一名探鬼主播讥蟆,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼纺阔!你這毒婦竟也來了瘸彤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤笛钝,失蹤者是張志新(化名)和其女友劉穎质况,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體玻靡,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拯杠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了啃奴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片潭陪。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖最蕾,靈堂內(nèi)的尸體忽然破棺而出依溯,到底是詐尸還是另有隱情,我是刑警寧澤瘟则,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布黎炉,位于F島的核電站,受9級(jí)特大地震影響醋拧,放射性物質(zhì)發(fā)生泄漏慷嗜。R本人自食惡果不足惜淀弹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庆械。 院中可真熱鬧薇溃,春花似錦、人聲如沸缭乘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽堕绩。三九已至策幼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間奴紧,已是汗流浹背特姐。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留黍氮,地道東北人到逊。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像滤钱,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子脑题,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

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

  • 本文出自 Eddy Wiki 件缸,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,118評(píng)論 0 14
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,957評(píng)論 1 18
  • 一、wait--notify--sleep Object obj = new Object(); obj.wait...
    fe0180bd6eaf閱讀 336評(píng)論 0 1
  • 本文主要講了java中多線程的使用方法叔遂、線程同步他炊、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法已艰、概述等痊末。 首先講...
    李欣陽閱讀 2,454評(píng)論 1 15
  • 很多人受到大的打擊就會(huì)一蹶不振,從此沒有了生機(jī)哩掺。今天學(xué)到了一個(gè)新的原因凿叠,很合理,就是因?yàn)樽詰佟?大概意思就是這種人...
    Universe2018閱讀 204評(píng)論 0 0