一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - java高并發的線程中斷的幾種方式詳解

java高并發的線程中斷的幾種方式詳解

2022-03-02 00:54路人甲Java Java教程

這篇文章主要介紹了Java線程中斷機制幾種方法及示例,向大家分享了這幾種方法的介紹幾代碼示例,具有一定參考價值,需要的朋友可以了解下。

通過一個變量控制線程中斷

代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.itsoku.chat05; 
import java.util.concurrent.TimeUnit;  
/**
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!   
 */
public class Demo1 {   
    public volatile static boolean exit = false;   
    public static class T extends Thread { 
        @Override  
        public void run() {
            while (true) { 
                //循環處理業務   
                if (exit) {
                    break
                }  
            }  
        }  
    }  
    public static void setExit() { 
        exit = true;   
    }  
    public static void main(String[] args) throws InterruptedException {   
        T t = new T(); 
        t.start(); 
        TimeUnit.SECONDS.sleep(3); 
        setExit(); 
    }  
}

代碼中啟動了一個線程,線程的run方法中有個死循環,內部通過exit變量的值來控制是否退出。 TimeUnit.SECONDS.sleep(3);讓主線程休眠3秒,此處為什么使用TimeUnit?TimeUnit使用更方便一些,能夠很清晰的控制休眠時間,底層還是轉換為Thread.sleep實現的。程序有個重點:volatile關鍵字,exit變量必須通過這個修飾,如果把這個去掉,程序無法正常退出。volatile控制了變量在多線程中的可見性,關于volatile前面的文章中有介紹,此處就不再說了。

通過線程自帶的中斷標志控制

示例代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.itsoku.chat05; 
import java.util.concurrent.TimeUnit;  
/**
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!   
 */
public class Demo2 {   
    public static class T extends Thread { 
        @Override  
        public void run() {
            while (true) { 
                //循環處理業務   
                if (this.isInterrupted()) {
                    break
                }  
            }  
        }  
    }  
    public static void main(String[] args) throws InterruptedException {   
        T t = new T(); 
        t.start(); 
        TimeUnit.SECONDS.sleep(3); 
        t.interrupt(); 
    }  
}

運行上面的程序,程序可以正常結束。線程內部有個中斷標志,當調用線程的interrupt()實例方法之后,線程的中斷標志會被置為true,可以通過線程的實例方法isInterrupted()獲取線程的中斷標志。

線程阻塞狀態中如何中斷?

示例代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.itsoku.chat05; 
import java.util.concurrent.TimeUnit;  
/**
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!   
 */
public class Demo3 {   
    public static class T extends Thread { 
        @Override  
        public void run() {
            while (true) { 
                //循環處理業務   
                //下面模擬阻塞代碼 
                try {  
                    TimeUnit.SECONDS.sleep(1000);  
                } catch (InterruptedException e) { 
                    e.printStackTrace();   
                }  
            }  
        }  
    }  
    public static void main(String[] args) throws InterruptedException {   
        T t = new T(); 
        t.start(); 
    }  
}

運行上面代碼,發現程序無法結束。

在此先補充幾點知識:

1.調用線程的interrupt()實例方法,線程的中斷標志會被置為true

2.當線程處于阻塞狀態時,調用線程的interrupt()實例方法,線程內部會觸發InterruptedException異常,并且會清除線程內部的中斷標志(即將中斷標志置為false)

那么上面代碼可以調用線程的interrupt()方法來引發InterruptedException異常,來中斷sleep方法導致的阻塞,調整一下代碼,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.itsoku.chat05; 
import java.util.concurrent.TimeUnit;  
/**
 * 微信公眾號:路人甲Java,專注于java技術分享(帶你玩轉 爬蟲、分布式事務、異步消息服務、任務調度、分庫分表、大數據等),喜歡請關注!   
 */
public class Demo3 {   
    public static class T extends Thread { 
        @Override  
        public void run() {
            while (true) { 
                //循環處理業務   
                //下面模擬阻塞代碼 
                try {  
                    TimeUnit.SECONDS.sleep(1000);  
                } catch (InterruptedException e) { 
                    e.printStackTrace();   
                    this.interrupt();  
                }  
                if (this.isInterrupted()) {
                    break
                }  
            }  
        }  
    }  
    public static void main(String[] args) throws InterruptedException {   
        T t = new T(); 
        t.start(); 
        TimeUnit.SECONDS.sleep(3); 
        t.interrupt(); 
    }  
}

運行結果:

?
1
2
3
4
5
java.lang.InterruptedException: sleep interrupted  
    at java.lang.Thread.sleep(Native Method)   
    at java.lang.Thread.sleep(Thread.java:340
    at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)  
    at com.itsoku.chat05.Demo3$T.run(Demo3.java:17)

程序可以正常結束了,分析一下上面代碼,注意幾點:

1.main方法中調用了t.interrupt()方法,此時線程t內部的中斷標志會置為true

2.然后會觸發run()方法內部的InterruptedException異常,所以運行結果中有異常輸出,上面說了,當觸發InterruptedException異常時候,線程內部的中斷標志又會被清除(變為false),所以在catch中又調用了this.interrupt();一次,將中斷標志置為false

3.run()方法中通過this.isInterrupted()來獲取線程的中斷標志,退出循環(break)

總結

當一個線程處于被阻塞狀態或者試圖執行一個阻塞操作時,可以使用 Thread.interrupt()方式中斷該線程,注意此時將會拋出一個InterruptedException的異常,同時中斷狀態將會被復位(由中斷狀態改為非中斷狀態)

內部有循環體,可以通過一個變量來作為一個信號控制線程是否中斷,注意變量需要volatile修飾

文中的幾種方式可以結合起來靈活使用控制線程的中斷

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://itsoku.blog.csdn.net/article/details/100036221

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 人人爽人人草 | 精品久久久久香蕉网 | 欧美日韩专区国产精品 | 久久91精品国产91久久户 | 冰雪奇缘1完整版免费观看 变形金刚第一部 | 日本一区二区三区国产 | 日本福利视频网站 | 国产亚洲欧美一区二区三区 | 精品久久久久久亚洲 | 99这里精品 | 美女张开腿让我了一夜 | 日韩欧美国产综合精品 | 黄动漫车车好快的车车双女主 | 99久久精品免费看国产 | 丝瓜污污视频 | 99精品偷自拍 | 欧美人成绝费网站色www吃脚 | 98成人网| 天堂在线观看中文字幕 | 亚洲天堂激情 | 日本特级a禁片在线播放 | fc2免费人成在线 | 猛吸奶水的老汉 | 欧美一区二区三区四区五区六区 | 国产一级在线免费观看 | 成人在线观看免费视频 | 美女精品永久福利在线 | 亚洲va欧美va国产va天堂影 | 亚洲激情 欧美 | 韩国女主播一区二区视频 | 日本小视频免费 | 国产精品免费久久久久影院小说 | 蹭蹭妈妈的朋友小说 | 国产精品视频久 | freehd182d动漫 | 日韩经典在线观看 | 国产亚洲欧美在线中文bt天堂网 | 好大好硬好深好爽想要之黄蓉 | 国产日韩欧美不卡www | 99精品国产高清自在线看超 | 免费视频完整版在线观看网站 |