多線程學習之如何中斷線程

在很多時候我們需要中斷或者取消一些任務,在Java中并沒有提供一些好的方法來終止線程刻恭。

中斷原因

我們的任務或者線程一般情況下都會讓它正常的執(zhí)行直到結束尸执,然而有時候也有可能我們需要提前結束這個任務或者線程峰伙。但是一個任務或者線程的執(zhí)行涉及系統、內存程帕、棧住练、數據等的完整性,要提前結束并不簡單愁拭,在Java中也沒有提供好的安全地終止線程讲逛。

取消的原因有很多比如用戶取消、一定時間未成功提前結束敛苇、錯誤妆绞、服務器關閉等,一個好的軟件特點之一就是能夠很完善的處理失敗枫攀、關閉和取消的過程括饶。

中斷方法一:中斷標志位

我們可以設置一個已關閉的標志位,當任務或者線程運行的時候先判斷標志位的狀態(tài)来涨,如果是已經關閉那個這個任務或者線程就直接結束图焰,不過這個標志位需要用volatile關鍵字修飾,否則可能其他線程已經修改了任務可能仍然在運行蹦掐。

這種方法可以解決一部分問題技羔,但是當任務可能會被阻塞的時候就會出現問題,就像之前的生產者卧抗、消費者模式藤滥,如果生產者通過循環(huán)往隊列里面加元素,在每次循環(huán)之前都要判斷中斷標志位社裆,如果結束了就不往隊列中put數據了拙绊,當消費者在某些情況下可能不在消費數據所以會設置標志位為已結束。此時如果阻塞隊列是滿的泳秀,而剛好生產者在put阻塞中标沪,由于消費者不在消費,生產者線程就會永遠處于阻塞狀態(tài)嗜傅。

中斷方法二:Thread.interrupt()

上一個中斷方法在遇到阻塞方法時就會出現永久阻塞狀態(tài)的問題金句,所以Java的Thread提供了一個boolean類型的中斷狀態(tài),通過interrupt方法可以設置狀態(tài)為中斷吕嘀,isInterrupted方法會返回中斷狀態(tài)违寞,靜態(tài)的interrupted方法會清除當前線程的中斷狀態(tài)贞瞒,并返回它之前的值,這是清除中斷狀態(tài)的唯一方法坞靶。

一些阻塞方法如Thread.sleep憔狞、Object.wait蝴悉、阻塞隊列的take彰阴、put方法都會檢查線程中斷狀態(tài),并且在發(fā)現中斷時提前返回拍冠,他們響應中斷時執(zhí)行的操作包括:清除中斷狀態(tài)尿这,拋出InterruptedException,表示阻塞操作因為中斷而提前操作庆杜,這就是這些方法都會拋出InterruptedException的原因射众,反之如果拋出InterruptedException則說明線程被中斷,接受到這個信息后我們可以方便的處理后續(xù)流程晃财。

interrupt方法并不會真正的中斷一個正在運行的線程叨橱,而只是發(fā)出中斷請求,然后由線程在下一個合適的時刻中斷自己断盛,這樣才能保證數據結構不會被破壞罗洗。同時要小心調用interrupted方法,它會清除當前線程的中斷狀態(tài)钢猛,所以在方法的返回值是true時除非你本來想屏蔽這個中斷伙菜,否則必須要處理,可以拋出InterruptedException或者再次調用interrupt中斷線程命迈。

中斷方法三:利用Future

可以把任務封裝成一個Future贩绕,Future中有一個方法“boolean cancel(boolean mayInterruptIfRunning);”如果參數為true并且任務正在某個線程中執(zhí)行,那么這個線程就能夠被中斷壶愤,如果參數為false則表示如果任務還沒有運行那就不要運行(有些任務不處理中斷)淑倾。

還存在一些情況可能通過以上方法仍然無法中斷或取消,比如IO阻塞或者等待獲取鎖的阻塞征椒,不過Java中也有一些解決辦法娇哆,比如Socket則是可以通過關閉socket,對于鎖可以在Lock類中提供了lockInterruptibly方法陕靠,它可以支持在等在一個鎖的同時去響應中斷信號迂尝。

JVM的關閉

JVM關閉也分為正常關閉和強行關閉,強行關閉方式比如殺死JVM進程剪芥。這里主要說明的是正常關閉垄开,比如System.exit獲取程序正常執(zhí)行結束。在正常關閉時税肪,JVM會首先調用注冊的關閉鉤子(通過“Runtime.getRuntime().addShutdownHook();”添加的一些關閉程序時必須執(zhí)行的方法溉躲,比如清理一些臨時文件之類的)榜田,當鉤子關閉完成后JVM會運行終結器,最后停止锻梳。JVM關閉并不會關閉正在運行中的線程箭券,而是在JVM關閉完成后強行關閉。如果關閉鉤子或者終結器沒有執(zhí)行完成疑枯,那么JVM的關閉進程就會被掛起辩块,然后強行關閉JVM。

兩個重要知識點:

線程分兩種:普通線程和守護線程荆永,jvm啟動時創(chuàng)建的線程除了主線程外都是守護線程废亭,當創(chuàng)建一個線程時新線程會繼承狀態(tài),所以主線程默認情況下創(chuàng)建的線程都是普通線程具钥。

當一個線程退出時JVM會檢查其他正在運行的線程豆村,如果所有都是守護線程,那么JVM會執(zhí)行正常退出操作骂删。

終結器:垃圾回收器對那些定義了finalize方法的對象在回收后會調用finalize方法掌动,不過finalize方法有性能問題,所以現在已經避免使用宁玫。

總結

啟動一個任務或線程很簡單粗恢,但是要提前取消或者關閉卻比較復雜,一個好的軟件是應該能夠很好的支持取消和關閉的撬统。

Java程序員日常學習筆記适滓,如理解有誤歡迎各位交流討論!


?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末恋追,一起剝皮案震驚了整個濱河市凭迹,隨后出現的幾起案子,更是在濱河造成了極大的恐慌苦囱,老刑警劉巖盏缤,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峻黍,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機间涵,發(fā)現死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進店門桩皿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來香缺,“玉大人坐漏,你說我怎么就攤上這事≈霸保” “怎么了麻蹋?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長焊切。 經常有香客問我扮授,道長芳室,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任刹勃,我火速辦了婚禮堪侯,結果婚禮上,老公的妹妹穿的比我還像新娘荔仁。我一直安慰自己伍宦,他們只是感情好,可當我...
    茶點故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布咕晋。 她就那樣靜靜地躺著雹拄,像睡著了一般收奔。 火紅的嫁衣襯著肌膚如雪掌呜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天坪哄,我揣著相機與錄音质蕉,去河邊找鬼。 笑死翩肌,一個胖子當著我的面吹牛模暗,可吹牛的內容都是我干的。 我是一名探鬼主播念祭,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼兑宇,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了粱坤?” 一聲冷哼從身側響起隶糕,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎站玄,沒想到半個月后枚驻,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡株旷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年再登,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晾剖。...
    茶點故事閱讀 38,650評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡锉矢,死狀恐怖,靈堂內的尸體忽然破棺而出齿尽,到底是詐尸還是另有隱情沽损,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布雕什,位于F島的核電站缠俺,受9級特大地震影響显晶,放射性物質發(fā)生泄漏。R本人自食惡果不足惜壹士,卻給世界環(huán)境...
    茶點故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一磷雇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧躏救,春花似錦唯笙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至少办,卻和暖如春苞慢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背英妓。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工挽放, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蔓纠。 一個月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓辑畦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親腿倚。 傳聞我的和親對象是個殘疾皇子纯出,可洞房花燭夜當晚...
    茶點故事閱讀 43,527評論 2 349