掌握并發控制的“急剎車”藝術!

當一個線程運行時,另外一個線程可以直接通過interrupt方法對其設置中斷標志位。

判斷線程是否中斷的2個方法:

// 判斷目標線程是否被中斷,不會清除中斷標記。
Thread.currentThread().isInterrupted()
// 判斷目標線程是否被中斷,會清除中斷標記
Thread.interrupted()

示例1:判斷目標線程是否被中斷,不會清除中斷標記

public class Task2 implements Runnable {@Overridepublic void run() {System.out.println("線程的run方法開始執行");// 判斷線程是否被中斷,不會清除中斷標記if (Thread.currentThread().isInterrupted()) {System.out.println("線程被中斷");}if (!Thread.currentThread().isInterrupted()) {// 因為上面的Thread.currentThread().isInterrupted()不會清除中斷標記// 因此線程保留了中斷標記,所以該循環不會執行,程序不會輸出1-3的數字for (int i = 0; i < 3; i++) {System.out.println("線程運行,i=" + i);}}System.out.println("線程的run方法執行結束");}
}運行上面的測試類Task2InterruptTest,程序運行結果:
線程的run方法開始執行
線程被中斷
線程的run方法執行結束

以上的程序說明,Thread.currentThread().isInterrupted()不會清除中斷標記,因此線程保留了中斷標記,所以該循環不會執行,程序不會輸出1-3的數字。

示例2:判斷目標線程是否被中斷,清除中斷標記

public class Task3 implements Runnable {@Overridepublic void run() {System.out.println("線程的run方法開始執行");// 判斷線程是否被中斷,會清除中斷標記if (Thread.interrupted()) {System.out.println("線程被中斷");}if (!Thread.currentThread().isInterrupted()) {// 因為上面的Thread.interrupted()會清除中斷標記// 因此線程的中斷標記沒有了,線程繼續執行,程序會輸出1-3的數字for (int i = 0; i < 3; i++) {System.out.println("線程運行,i=" + i);}}System.out.println("線程的run方法執行結束");}
}// 測試類
public class Task3InterruptTest {public static void main(String[] args) {Task3 task = new Task3();Thread thread = new Thread(task);thread.start();thread.interrupt(); // 中斷thread線程的執行}
}程序運行結果:
線程的run方法開始執行
線程被中斷
線程運行,i=0
線程運行,i=1
線程運行,i=2
線程的run方法執行結束

以上的程序說明,Thread.interrupted()會清除中斷標記,thread線程沒有了中斷標記,因此Thread.currentThread().isInterrupted()的結果為false,所以線程繼續執行,程序會輸出1-3的數字。

下面我們來看一下如果處于阻塞狀態(調用了sleep、join等方法)的線程,被執行了中斷操作,會有什么樣的結果。

答案很明顯,處于阻塞狀態下的線程被執行了中斷操作,會拋出中斷異常InterruptedException。

示例3:處于阻塞狀態的線程被執行中斷操作的結果演示

public class Task4 implements Runnable {@Overridepublic void run() {System.out.println("線程的run方法開始執行");try {Thread.sleep(5000); // 線程休眠5秒System.out.println("線程完成5秒鐘的休眠");} catch (InterruptedException e) {e.printStackTrace();}System.out.println("線程的run方法執行結束");}
}// 測試類
public class Task4InterruptTest {public static void main(String[] args) {Task4 task = new Task4();Thread thread = new Thread(task);thread.start();try {Thread.sleep(2000); // 主線程休眠2秒} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt(); // 中斷thread線程的執行}
}程序運行結果:
線程的run方法開始執行
java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at testThread.day3.Task4.run(Task4.java:8)at java.lang.Thread.run(Unknown Source)
線程的run方法執行結束

通過上面的程序可以看出,處于阻塞狀態下的線程被執行了中斷操作,會拋出中斷異常InterruptedException,但是thread線程在捕獲到異常后,輸出了“線程的run方法執行結束”的文字,說明thread線程在接收到中斷指令后,并沒有中斷線程的執行,而是繼續向下執行。

通過以上的程序示例,我們可以得出一個結論,那就是線程在執行了中斷指令后,其實是給線程發了一個中斷信號,線程被打上中斷標記,如果線程沒有對中斷標記進行判斷,做相應的處理,那么線程默認會繼續執行,直到線程操作結束。

那么,問題來了,處于阻塞狀態的線程被執行中斷指令后,如何做到線程的中斷呢,請看以下的代碼。

示例4:處于阻塞狀態的線程被執行中斷指令后,立即把線程中斷

public class Task5 implements Runnable {@Overridepublic void run() {System.out.println("線程的run方法開始執行");try {Thread.sleep(5000); // 線程休眠5秒System.out.println("線程完成5秒鐘的休眠");} catch (InterruptedException e) {// 在catch塊里進行處理,再次調用interrupt方法,線程是否會中斷執行呢?System.out.println("線程被中斷");Thread.currentThread().interrupt();}for (int i = 0; i < 3; i++) {System.out.println(i);}System.out.println("線程的run方法執行結束");}
}// 測試類
public class Task5InterruptTest {public static void main(String[] args) {Task5 task = new Task5();Thread thread = new Thread(task);thread.start();try {Thread.sleep(2000); // 主線程休眠2秒} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt(); // 中斷thread線程的執行}
}程序運行結果
線程的run方法開始執行
線程被中斷
0
1
2
線程的run方法執行結束

通過上面的程序,大家會感到奇怪,明明已經在catch塊里,又調用了Thread.currentThread().interrupt()方法,但是線程還是沒有中斷,繼續往下執行。

在這里再一次和大家要強調說明的就是,調用線程的interrupt()方法,不是說線程就不執行了,而是向線程發出了中斷信號,線程被打上中斷標記,如果想讓線程中斷,必須在run方法里對中斷信號進行響應,讓程序return返回到被調用處,才能使線程真正的中斷。

示例5:正確的讓線程中斷的例子

public class Task6 implements Runnable {@Overridepublic void run() {System.out.println("線程的run方法開始執行");try {Thread.sleep(5000); // 線程休眠5秒System.out.println("線程完成5秒鐘的休眠");} catch (InterruptedException e) {// 在catch塊里進行處理,讓程序返回被調用處System.out.println("線程被中斷");return;}for (int i = 0; i < 3; i++) {System.out.println(i);}System.out.println("線程的run方法執行結束");}
}// 測試類
public class Task6InterruptTest {public static void main(String[] args) {Task6 task = new Task6();Thread thread = new Thread(task);thread.start();try {Thread.sleep(2000); // 主線程休眠2秒} catch (InterruptedException e) {e.printStackTrace();}thread.interrupt(); // 中斷thread線程的執行}
}程序運行結果:
線程的run方法開始執行
線程被中斷

通過上面的程序,可以看出,使用return可以做到中斷線程。

線程的中斷其實是為了優雅的停止線程的運行,為了不使用stop方法而設置的。因為JDK不推薦使用stop方法進行線程的停止,因為stop方法會釋放鎖并強制終止線程,會造成執行一半的線程終止,帶來數據的不一致性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/17578.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/17578.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/17578.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【職業教育培訓機構小程序】教培機構“招生+教學”有效解決方案

教培機構“招生教學”有效解決方案在數字化轉型的浪潮中&#xff0c;職業教育培訓機構面臨著提升教學效率、拓寬招生渠道、增強學員互動等多重挑戰。小程序作為一種新興的移動應用平臺&#xff0c;為解決這些痛點提供了有效途徑。 一、職業教育培訓機構小程序的核心功能 &…

Laravel 圖片添加水印

和這個配合使用 Laravel ThinkPhP 海報生成_laravel 制作海報-CSDN博客 代碼 //水印 $x_length $imageInfo[0]; $y_length $imageInfo[1];$color imagecolorallocatealpha($posterImage, 255, 255, 255, 70); // 增加透明度參數alpha$font_size 40; //字體大小 $angle …

HTML靜態網頁成品作業(HTML+CSS)——家鄉沅陵介紹網頁(1個頁面)

&#x1f389;不定期分享源碼&#xff0c;關注不丟失哦 文章目錄 一、作品介紹二、作品演示三、代碼目錄四、網站代碼HTML部分代碼 五、源碼獲取 一、作品介紹 &#x1f3f7;?本套采用HTMLCSS&#xff0c;未使用Javacsript代碼&#xff0c;共有1個頁面。 二、作品演示 三、代…

條款9:利用destructors避免泄露資源

對指針說拜拜。承認吧&#xff0c;你從未真正喜歡過它&#xff0c;對不&#xff1f; 好&#xff0c;你不需要對所有指針說拜拜&#xff0c;但是你真的得對那些用來操控局部性資源(local resources&#xff09;的指針說莎唷娜拉了。 舉個例子&#xff0c;你正在為“小動物收養…

Flutter 中的 CircularProgressIndicator 小部件:全面指南

Flutter 中的 CircularProgressIndicator 小部件&#xff1a;全面指南 在 Flutter 應用開發中&#xff0c;加載指示器是提供用戶反饋的重要組成部分&#xff0c;特別是在需要等待數據加載的場景中。CircularProgressIndicator 是 Flutter 提供的一個表現圓形加載動畫的小部件。…

Python進階:探索Python標準庫和第三方庫

在前兩篇文章中,我們介紹了Python的基本語法和面向對象編程。在這篇文章中,我們將深入探索Python的標準庫以及一些常用的第三方庫。Python的強大之處不僅在于其簡潔的語法,還在于豐富的庫生態系統。通過使用這些庫,你可以更高效地完成各種任務,從文件操作到數據分析、網絡…

godot4.2 + GDextension c++在 vs code 中斷點調試配置

游戲開發中如果做不到自己編寫的代碼做斷點調試&#xff0c;無不是瞎子摸象&#xff0c;特別是C這么底層的語言。這2天開始在VS studio中折騰&#xff0c;一直折騰不出結果&#xff0c;幾次想要放棄GODOT。最終今天在VS code中搞定了這斷點調試C代碼。 在上一篇文章我已經做好了…

React hooks - useContext

useContext 用法使用以非侵入的方式使用 Context使用 useContext 重構 useReducer 案例 用法 實現多層組件的數據傳遞 在全局創建 Context 對象在父組件中使用 Context.Provider 提供數據在子組件中使用 useContext 使用數據 import React, { useContext } from react // 全局…

全網爆火Remini 粘土濾鏡風格,我用ComfyUI一鍵生成了(保姆級教程)!

一、火爆全網的Remini&#xff01; Remini真的火爆了&#xff01;最近大家的朋友應該都被粘土濾鏡刷屏了。 小紅書上粘土濾鏡、粘土特效的帖子動不動就是幾百萬瀏覽量&#xff0c;幾千贊。 在有些電商平臺上還有人接單&#xff0c;幫忙定制remini粘土風格的照片&#xff01; …

解釋瀏覽器緩存和本地存儲的區別,以及如何實現事件的防抖和節流

1:瀏覽器緩存和本地存儲的區別: 瀏覽器緩存:瀏覽器緩存是一種臨時性的數據存儲,用于提高網頁加載速度。緩存的數據存儲在內存或磁盤中,當用戶再次訪問相同的資源時,瀏覽器會優先從緩存中讀取數據,而不是從服務器重新請求。緩存的數據可以在瀏覽器關閉后自動清除,或者根據 HTT…

vue+three.js實現3d系統的搭建

1.首先node.js是12.22版本的&#xff0c;安裝three.js可以參考這篇文章 直接用Threejs入門-安裝教程_安裝three.js-CSDN博客 直接在終端安裝three.js即可 npm install --save three 在相同目錄下安裝vite構建工具 npm install --save-dev vite 在項目里面看package.json中…

神秘顧客調查:第三方渠道監測如何操作?

第三方渠道監測是指通過專業的第三方機構或服務商&#xff0c;對企業的銷售渠道進行系統化的監督和評估。這種監測幫助企業了解各渠道的表現&#xff0c;確保合規性&#xff0c;提升市場競爭力。深圳神秘顧客市場調查限公司&#xff08;SMS&#xff09;總結了第三方渠道監測的操…

【安裝筆記-20240528-Linux-在 Vultr 云服務器上安裝 OpenWRT】

安裝筆記-系列文章目錄 安裝筆記-20240528-Linux-在 Vultr 云服務器上安裝測試 OpenWRT 文章目錄 安裝筆記-系列文章目錄安裝筆記-20240528-Linux-在 Vultr 云服務器上安裝測試 OpenWRT 前言一、軟件介紹名稱&#xff1a;OpenWRT主頁官方介紹 二、安裝步驟測試版本&#xff1a…

多function-calling 調用

多function-calling 調用 接上一篇function-calling調用&#xff0c;本篇實現了一個多function-calling的調用。OpenAI會根據function的描述自己來判斷應該調用哪個function。最終調用function的動作是由我們來決定的&#xff0c;當然你也可以不調對應的函數。 兩個函數分別是…

案例研究|MeterSphere助力萬物云構建高效自動化測試平臺

萬物云空間科技服務股份有限公司&#xff08;以下簡稱為“萬物云”&#xff09;&#xff0c;前身為萬科物業發展股份有限公司&#xff0c;是國內領先的物管龍頭上市公司。作為一家科技引領的全域空間服務商&#xff0c;萬物云致力于打造產業級共享服務平臺&#xff0c;基于空間…

1. lambda初體驗

首先聲明一個函數式接口&#xff0c;就只接口內只有一個抽象方法 //函數式接口 public interface Factory {Object getObject();}接口實現類 public class SubClass implements Factory {Overridepublic Object getObject() {return new User();}}User類 public class User …

酒店提前線上訂房小程序源碼系統 PHP+MySQL組合開發 源碼開源可二開 帶完整的安裝代碼包以及搭建教程

系統概述 隨著移動互聯網的普及&#xff0c;越來越多的人習慣通過手機進行酒店預訂。傳統的線下訂房方式逐漸無法滿足用戶的需求&#xff0c;酒店提前線上訂房小程序的出現成為必然趨勢。該源碼系統的開發旨在為酒店提供一個便捷、高效的線上訂房平臺&#xff0c;提升用戶體驗…

基于微信小程序+ JAVA后端實現的【醫院掛號預約系統】 設計與實現 (內附設計LW + PPT+ 源碼+ 演示視頻 下載)

項目名稱 項目名稱&#xff1a; 《基于微信小程序的醫院掛號預約系統設計與實現》 項目技術棧 該項目采用了以下核心技術棧&#xff1a; 后端框架/庫&#xff1a; Java, SSM框架數據庫&#xff1a; MySQL前端技術&#xff1a; 微信小程序, uni-app 項目展示 全文概括 本…

設置單群聊消息擴展

根據消息 ID &#xff0c;對單聊會話或群聊會話中已經發送的消息設置擴展信息。每次最多可以設置 100 個擴展屬性信息&#xff0c;最多可設置 300 個。 通過 Server API 操作消息擴展&#xff0c;默認不會向操作者的客戶端同步&#xff0c;會導致擴展信息不一致。如有需要&…

MySQL觸發器實戰:自動執行的秘密

歡迎來到我的博客&#xff0c;代碼的世界里&#xff0c;每一行都是一個故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交給時間 &#x1f3e0; &#xff1a;小破站 MySQL觸發器實戰&#xff1a;自動執行的秘密 前言觸發器的定義和作用觸發器的定義和作用觸發器的…