協作,才能更好的中斷執行緒
聊起中斷,大家可能最熟悉的例子就是執行緒休眠。下面就是一個執行緒休眠的 demo,在這個例子中,當我們呼叫 sleep
方法,該方法將會丟擲一個需要捕獲的中斷異常,這裡捕獲該異常並直接返回。
for (int i = 0; i < somethings.size(); i++) { // 休眠 4 s try { Thread.sleep(4000); } catch (InterruptedException e) { // 丟擲中斷異常 return; } // 輸出 System.out.println(somethings.get(i)); }
除了 InterruptedException
中斷異常,另外還有三個中斷相關的方法,三個方法都與執行緒相關。
- thread#interrupt
- Thread#interrupted
- thread#isInterrupted
interrupt
方法用於中斷執行緒,但是並不是說該方法就能直接使執行緒停止。
下面使用 interrupt
中斷執行緒,這裡我們期望中斷直接停止子執行緒輸出。但是當主執行緒呼叫子執行緒 interrupt
方法,子執行緒並卻沒有被終止,還在繼續列印數字。
Runnable interruptedTask=new Runnable() { @Override public void run() { for (int i = 0; i <Integer.MAX_VALUE ; i++) { System.out.println(i); } } }; Thread interruptThread=new Thread(interruptedTask); interruptThread.start(); // 休眠 5 s, TimeUnit.SECONDS.sleep(2); // 中斷當前執行緒 interruptThread.interrupt(); // 再次休眠,觀察子執行緒 TimeUnit.SECONDS.sleep(2);
引用 Java 官方對於中斷的解釋:
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate
中斷僅僅只是表明這個執行緒可以停止,但是執行緒是否停止完全取決於執行緒自己。只有執行緒相互協作,才能更好的停止執行緒。
每個執行緒都包含一個內部標誌,用來表示中斷狀態。呼叫執行緒的 interrupt
方法將會設定該狀態位,對於 Thread#sleep
等阻塞方法,將會丟擲 InterruptedException
,並清除中斷標誌。
我們可以使用 thread#isInterrupted
或 Thread#interrupted
檢查中斷狀態。但是需要注意,兩個方法存在一些區別,Thread#interrupted
為靜態類方法,該方法檢測到中斷之後就會清除中斷標誌。
上面的方法我們只要加上中斷狀態判斷就也可以停止執行緒。
Runnable interruptedTask=new Runnable() {
@Override
public void run() {
for (int i = 0; i <Integer.MAX_VALUE ; i++) {
// 一旦檢測到中斷標誌,停止執行緒
if(Thread.interrupted()){
System.out.println("interrupted!!!!");
break;
}
System.out.println(i);
}
}
};
Thread interruptThread=new Thread(interruptedTask);
interruptThread.start();
// 休眠 5 s,
TimeUnit.SECONDS.sleep(2);
// 中斷當前執行緒
interruptThread.interrupt();
// 再次休眠,觀察子執行緒
TimeUnit.SECONDS.sleep(2);
}
中斷最佳實踐
不要隨意『吃掉』中斷異常
由於中斷異常是一個 checked exception,我們不得不需要處理該異常。如果我們可以保證該異常不影響應用,我們可以直接『吃掉』這個異常。其他情況下我們需要正確處理這個異常。
最簡單的做法就是不處理該異常,直接向上丟擲中斷異常,讓上層呼叫者決定如何處理。
但是有些情況下,卻不適合上面的做法,這種情況下我們需要在 catch 中處理中斷。如果實在不知道如何處理,那就是記錄該異常,並使用日誌方式輸出。
中斷不會停止阻塞 IO
上面我們說到,對於一些阻塞方法如 Thread#sleep
,將會丟擲中斷異常。但是對於 Socket 等阻塞 IO 呼叫,並不會丟擲這個異常。也就是說中斷並不會停止阻塞 IO 的呼叫。
這是因為當呼叫 Thread#sleep
等阻塞方法時,Java 執行緒狀態將會從 RUNNABLE
轉變為 TIMED_WAITING
或 WATTING
。而當執行緒阻塞在 IO 讀取時,Java 執行緒實際狀態卻還是 RUNNABLE
。如果你對這個執行緒狀態還有疑惑,可以閱讀下這篇文章 面試官:都說阻塞 I/O 模型將會使執行緒休眠,為什麼 Java 執行緒狀態卻是 RUNNABLE?,深入理解一下執行緒狀態。
本文首發於studyidea.cn
歡迎關注我的公眾號:程式通事,獲得日常乾貨推送。如果您對我的專題內容感興趣,也可以關注我的部落格:studyidea.cn
相關推薦
協作,才能更好的中斷執行緒
聊起中斷,大家可能最熟悉的例子就是執行緒休眠。下面就是一個執行緒休眠的 demo,在這個例子中,當我們呼叫 sleep 方法,該方法將會丟擲一個需要捕獲的中斷異常,這裡捕獲該異常並直接返回。 for (int i = 0; i < somethings.size(); i++) {
擁抱Android開發的變化,才能更好的擁抱未來!
近期很多同學都問過我這樣的問題。 “現在學習Android開發還有前景嗎?” “Android開發還有什麼可以研究的?” 大家對於職業的未來,都有一些迷茫和焦慮,為什麼會這樣呢? 現在網際網路行業,各大公司已經從爭奪使用者轉為爭奪使用者時長。而小程式、快應用的崛起,也讓許多 App
先照顧好自己,才能更好的去照顧別人
其實大城市裡打拼吧,真的是不容易。曾經我也幻想過,要是哪天深夜,我突然發高燒,站不起來也喊不出來,死了都沒人知道,想想都好可怕....... 事實證明,想多了,因為我百毒不侵啊。 無數次敲著程式碼的時候,會胸悶啊。然後趕緊喝口水,站起來向遠方眺望下,或者就是存粹的站起來站兩分鐘。。 還有幾次吃晚
一、多執行緒基礎概念、實現執行緒三種方法、中斷執行緒方法,以及執行緒狀態轉化
1、CPU核心數和執行緒數的關係 1:1的關係,引入超執行緒之後,就是1:2 2、cpu時間輪轉機制,即RR排程 3、程序和執行緒 程序:程式執行資源分配最小單位,程序內部有多個執行緒,多個執行緒之間會共享程序資源 執行緒:CPU排程的最小單位 4、並行和併發
從身邊開源開始學習,用過才能更好理解程式碼
2015年12月20日,雲棲社群上線。2018年12月20日,雲棲社群3歲。 阿里巴巴常說“晴天修屋頂”。 在我們看來,寒冬中,最值得投資的是學習,是增厚的知識儲備。 所以社群特別製作了這個專輯——分享給開發者們20個彌足珍貴的成長感悟,50本書單。 多年以後,再回首2018-19年,留給我們自己的,
雲棲專輯 | 阿里開發者們的第3個感悟:從身邊開源開始學習,用過才能更好理解程式碼
2015年12月20日,雲棲社群上線。2018年12月20日,雲棲社群3歲。 阿里巴巴常說“晴天修屋頂”。 在我們看來,寒冬中,最值得投資的是學習,是增厚的知識儲備。 所以社群特別製作了這個專輯——分享給開發者們20個彌足珍貴的成長感悟,50本書單。 多年以後,再回首2018-19年,留給我們自
MQTT是IBM開發的一個即時通訊協議,構建於TCP/IP協議上,是物聯網IoT的訂閱協議,借助消息推送功能,可以更好地實現遠程控制
集合 cap 消息處理 簡易 遠程控制 mes ogr 設計思想 成本 最近一直做物聯網方面的開發,以下內容關於使用MQTT過程中遇到問題的記錄以及需要掌握的機制原理,主要講解理論。 背景 MQTT是IBM開發的一個即時通訊協議。MQTT構建於TCP/IP協議上
當我們需要部署微服務的時候,哪個更好?
hit 額外 應用生命周期 更多 .html 服務架構 功能 ros 缺點 當我們需要部署微服務的時候,哪個更好?Spring Cloud還是Kubernetes?答案是都可以,只是各自有其優勢。 Spring Cloud 和 Kubernetes 都宣稱自己是開發和運行微
ResNeXt——與 ResNet 相比,相同的參數個數,結果更好:一個 101 層的 ResNeXt 網絡,和 200 層的 ResNet 準確度差不多,但是計算量只有後者的一半
模式 這樣的 cap dfa 不同 dual 重復 ORC 但是 from:https://blog.csdn.net/xuanwu_yan/article/details/53455260 背景 論文地址:Aggregated Residual Transformati
QoS最佳實踐,實現更好的帶寬管理
哪些 重新 開發 鏈路 定義 設備 中標 處理 服務 服務質量(QoS)使管理員能夠在通過公司網絡時確定某些數據流量的優先級。但是為了使QoS工作,必須首先進行大量的規劃和協調。如果你的網絡遇到帶寬和延遲問題,請確保遵循這些最佳實踐指南,以便使用QoS技術實現更好的帶寬管理
呼叫Spring所管理的bean的方法時候,為何不會出現執行緒安全問題?
首先jvm會在記憶體中開闢一塊儲存空間做為執行緒棧空間,每個執行緒都有自己的棧(後進先出)。 呼叫方法時,會在棧中壓入一個棧幀,用來儲存這個方法的引數和區域性變數; 方法返回時 ,棧幀就會彈出,方法的引數和區域性變數就會清除; 方法呼叫時,呼叫棧不斷處於漲落之中,如果呼叫的層級過深,
關於程序,執行緒,多程序和多執行緒的網路程式設計
程序執行緒網路 多工程式設計 : 可以有效的利用計算機資源,同時執行多個任務 程序 : 程序就是程式在計算機中一次執行的過程 程序和程式的區別: 程式是一個靜態檔案的描述,不佔計算機的系統資源 程序是一個動態的過程,佔有cpu記憶體等資源,有一定的生命週期 * 同一個程式的不同執行過程即為不同的程序
何愷明大神的「Focal Loss」,如何更好地理解?
轉自:http://blog.csdn.net/c9Yv2cf9I06K2A9E/article/details/78920998 作者丨蘇劍林 單位丨廣州火焰資訊科技有限公司 研究方向丨NLP,神經網路 個人主頁丨kexue.fm 前言
jstack簡單使用,定位死迴圈、執行緒阻塞、死鎖等問題
當我們執行java程式時,發現程式不動,但又不知道是哪裡出問題時,可以使用JDK自帶的jstack工具去定位; 廢話不說,直接上例子吧,在window平臺上的; 一、死迴圈 package software.architect.OtherAnalyzer.main; public
關於併發/並行,阻塞/非阻塞,同步/非同步及程序/執行緒的理解
1. 阻塞,非阻塞 一個執行緒/程序經歷的5個狀態,建立,就緒,執行,阻塞,終止。各個狀態的轉換條件如上圖,其中有個阻塞狀態,就是說當執行緒中呼叫某個函式,需要IO請求,或者暫時得不到競爭資源的,作業系統會把該執行緒
分清雲端儲存和雲備份,才能更理智的選擇“雲”
有關雲的炒作已經模糊了雲端儲存,以及雲備份恢復和還原(雲BURR)之間的界限。甚至使得雲端儲存和雲端的儲存,以及“同步和共享”這樣的概念差別變得模糊。許多供應商樂意與此,因為這使得他們的方案看上去對於潛在客戶更具吸引力。不過模糊不清的雲定義混淆了市場,妨礙了技術部署和推進的速度,並最終損害了市場中的
Web應用啟動時,後臺自動啟動一個執行緒(轉)
原文:http://blog.sina.com.cn/s/blog_6810dfc20101ipzq.html Web應用啟動時,後臺自動啟動一個執行緒 (1)前言 前幾天,manager問道一個問題:能不能實現類似於cro
「阿里面試系列」面試加分項,從JVM層面瞭解執行緒的啟動和停止
文章簡介 這一篇主要圍繞執行緒狀態控制相關的操作分析執行緒的原理,比如執行緒的中斷,執行緒的通訊等,內容比較多,可能會分兩篇文章 阿里面試系列導讀:關注我的技術公眾號【架構師修煉寶典】一週出產1-2篇技術文章。 【阿里面試系列】搞懂併發程式設計,輕鬆應對80%的面試場景 【阿里面試系列】
#Java多執行緒學習,那麼如何實現多執行緒呢?
程序和執行緒的區別: 程序:每個程序都有獨立的程式碼和資料空間(程序上下文),程序間的切換會有較大的開銷,一個程序包含1–n個執行緒。 執行緒:同一類執行緒共享程式碼和資料空間,每個執行緒有獨立的執行棧和程式計數器(PC),執行緒切換開銷小。 執行緒和程序一樣分
linux定位應用問題的一些常用命令,特別針對記憶體和執行緒分析的dump命令
1.jps找出程序號,找到對應的程序號後面才好繼續操作 2.linux檢視程序詳細資訊 ps -ef | grep 程序ID 3. dump記憶體資訊 Jmap -dump:format=b,file=YYMMddhhmm