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

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Java教程 - 淺談Java線程Thread之interrupt中斷解析

淺談Java線程Thread之interrupt中斷解析

2021-03-28 15:57Ihesong Java教程

這篇文章主要介紹了Java線程Thread之interrupt中斷解析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

這一篇我們說(shuō)說(shuō)java線程thread的interrupt中斷機(jī)制。

中斷線程

線程的thread.interrupt()方法是中斷線程,將會(huì)設(shè)置該線程的中斷狀態(tài)位,即設(shè)置為true,中斷的結(jié)果線程是死亡、還是等待新的任務(wù)或是繼續(xù)運(yùn)行至下一步,就取決于這個(gè)程序本身。線程會(huì)不時(shí)地檢測(cè)這個(gè)中斷標(biāo)示位,以判斷線程是否應(yīng)該被中斷(中斷標(biāo)示值是否為true)。它并不像stop方法那樣會(huì)中斷一個(gè)正在運(yùn)行的線程。

判斷線程是否被中斷

判斷某個(gè)線程是否已被發(fā)送過(guò)中斷請(qǐng)求,請(qǐng)使用thread.currentthread().isinterrupted()方法(因?yàn)樗鼘⒕€程中斷標(biāo)示位設(shè)置為true后,不會(huì)立刻清除中斷標(biāo)示位,即不會(huì)將中斷標(biāo)設(shè)置為false),而不要使用thread.interrupted()(該方法調(diào)用后會(huì)將中斷標(biāo)示位清除,即重新設(shè)置為false)方法來(lái)判斷,下面是線程在循環(huán)中時(shí)的中斷方式:

?
1
2
3
while(!thread.currentthread().isinterrupted() && more work to do){
 do more work
}

interrupt之中斷狀態(tài)標(biāo)記

interrupt中斷機(jī)制中有如下方法:

  1. thread.interrupt(),設(shè)置當(dāng)前中斷標(biāo)記為true(類(lèi)似屬性的set方法)
  2. thread.isinterrupted(),檢測(cè)當(dāng)前的中斷標(biāo)記(類(lèi)似屬性的get方法)
  3. thread.interrupted(),檢測(cè)當(dāng)前的中斷標(biāo)記,然后重置中斷標(biāo)記為false(類(lèi)似屬性的get方法+set方法)

因此interrupt中斷機(jī)制并不是真正的將當(dāng)前線程中斷,而是一個(gè)中斷標(biāo)記的變化。我們先用例子來(lái)測(cè)試一下。

?
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
32
33
34
35
36
37
38
39
40
41
42
43
44
public class interrupttest {
 //這里用來(lái)打印消耗的時(shí)間
 private static long time = 0;
 private static void resettime(){
 time = system.currenttimemillis();
 }
 private static void printcontent(string content){
 system.out.println(content + "  時(shí)間:" + (system.currenttimemillis() - time));
 }
 
 public static void main(string[] args) {
 test1();
 }
 
 private static void test1(){
 thread1 thread1 = new thread1();
 thread1.start();
 //延時(shí)3秒后interrupt中斷
 try {
  thread.sleep(3000);
 } catch (interruptedexception e) {
  e.printstacktrace();
 }
 thread1.interrupt();
 printcontent("執(zhí)行中斷");
 }
 
 private static class thread1 extends thread{
 @override public void run() {
  resettime();
  int num = 0;
  while (true){
  if(isinterrupted()){
   printcontent("當(dāng)前線程 isinterrupted");
   break;
  }
  num++;
  if(num % 100 == 0){
   printcontent("num : " + num);
  }
  }
 }
 }
}

以上代碼是開(kāi)啟一個(gè)thread1線程,在thread1線程的while循環(huán)中不斷對(duì)num加1,每到100的倍數(shù)打印一次(防止打印太快)。然后主線程在sleep了3000毫秒后,調(diào)用thread1線程的interrupt方法。那么我們看看輸出結(jié)果:

淺談Java線程Thread之interrupt中斷解析

intterupt中斷

可以看到,在耗時(shí)3000毫秒左右,也就是主線程sleep之后執(zhí)行thread1.interrupt();后,thread1線程停止了,而thread1線程的停止是因?yàn)閣hile循環(huán)中的isinterrupted方法返回了true,所以break退出了while循環(huán),也就是說(shuō)interrupt和isinterrupted在這里起到的作用就相當(dāng)于setxx和getxx的作用,維護(hù)著一個(gè)boolean變量。

interrupt之中斷異常處理

當(dāng)然interrupt機(jī)制并不僅僅是一個(gè)中斷狀態(tài)位的變化和檢測(cè),它還可以進(jìn)行中斷異常的處理。我們知道thread.sleep()方法需要捕獲中斷異常,那接下來(lái)我們往其中添加一個(gè)sleep延時(shí)試試

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
while (true){
if(isinterrupted()){
 printcontent("當(dāng)前線程 isinterrupted");
 break;
}
num++;
//sleep一下
try {
 thread.sleep(1);
} catch (interruptedexception e) {
 e.printstacktrace();
}
 
if(num % 100 == 0){
 printcontent("num : " + num);
}
}

我們?cè)倏纯摧敵鼋Y(jié)果:

淺談Java線程Thread之interrupt中斷解析

intterupt中斷

這里我們會(huì)發(fā)現(xiàn),sleep睡眠之后,輸出的num值明顯小了好多(沒(méi)睡眠時(shí)num都達(dá)到10億的大小了,看來(lái)cpu執(zhí)行簡(jiǎn)單運(yùn)算還是非常快的),哈哈,不過(guò)這不是重點(diǎn),重點(diǎn)是是看到輸出了一個(gè)異常,還有就是輸出異常后,isinterrupted輸出返回false,thread1線程又繼續(xù)執(zhí)行下去了,并沒(méi)有退出while循環(huán)。那么這是為什么呢?我們只是加了一個(gè)sleep睡眠而已。

如果thread1線程中有執(zhí)行需要捕獲interruptedexception異常的操作,比如thread的sleep,join方法,object的wait,condition的await等,它是強(qiáng)制需要捕獲interruptedexception異常的,那么當(dāng)thread1.interrupt方法調(diào)用之后,它會(huì)給thread1線程拋出一個(gè)interruptedexception異常,那么在while循環(huán)中,就能捕獲到這個(gè)異常然后這個(gè)異常拋出之后,又會(huì)馬上將線程中斷標(biāo)識(shí)重置為false,因此在下次的while循環(huán)中判斷isinterrupted時(shí),它是false,也就不會(huì)break,然后while循環(huán)會(huì)一直執(zhí)行下去。

因此interrupt()方法會(huì)根據(jù)thread線程中的run方法里是否有必須捕獲interruptedexception異常的代碼,而做出不同操作:

  1. 如果沒(méi)有必須捕獲interruptedexception異常的代碼(比如thread.sleep()),則isinterrupted()會(huì)返回true,此時(shí)可以在isinterrupted的判斷中處理中斷變化。
  2. 如果有必須捕獲interruptedexception異常的代碼(比如thread.sleep()),則會(huì)拋出interruptedexception異常,并進(jìn)行捕獲,同時(shí)重置isinterrupted為false,此時(shí)得在異常捕獲中處理中斷變化。

interrupt的應(yīng)用場(chǎng)景

通常interrupt適用于在線程執(zhí)行中的循環(huán)標(biāo)記判斷,例如

?
1
2
3
while(!isinterrupted()){
 ...
}

但是如果在本次循環(huán)中出現(xiàn)阻塞了,那么線程就無(wú)法判斷下次的isinterrupted標(biāo)記,那么即便調(diào)用了interrupt()方法也無(wú)法退出循環(huán),也就無(wú)法退出線程。例如

?
1
2
3
4
5
6
while(!isinterrupted()){
 ...
 while(true){
  //線程卡在這里了,則無(wú)法響應(yīng)interrupte機(jī)制了
 }
}

這樣的話,interrupt就沒(méi)轍了,線程會(huì)一直執(zhí)行下去,不會(huì)被中斷停止。

測(cè)試?yán)硬榭?我的github--javatest

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://www.jianshu.com/p/7f1071293a18

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 任我行视频在线观看国语 | 欧美军人男同69gay | 国产精品不卡 | 啪一啪在线视频 | 欧美日韩国产一区二区三区在线观看 | 精品亚洲综合在线第一区 | 外国xxx| 好男人资源免费观看 | 欧美69巨大jizzsex | 男人晚上适合偷偷看的污污 | 日韩在线观看网站 | 成人观看免费大片在线观看 | 任我行视频在线观看国语 | 欧美日韩亚洲国内综合网俺 | 男人搡女人视频免费看 | 911精品国产亚洲日本美国韩国 | 臀精插宫NP文| 国产欧美日韩图片一区二区 | 黑人好大好硬好深好爽想要h | 午夜视频一区二区三区 | 久久99精品涩AV毛片观看 | 青青草国产青春综合久久 | 白丝尤物的下面被疯狂蹂躏 | 色欲麻豆国产福利精品 | 日日摸日日碰夜夜爽97纠 | naruto tube18动漫 mm131亚洲精品久久 | 毛片免费的| 日本视频观看 | 999任你躁在线精品免费不卡 | 雪恋电影完整版免费观看 | 午夜视频网站 | 天天摸天天操天天爽 | 日韩资源| nxgx国产| 日韩欧美一级大片 | 国产精品午夜性视频网站 | 亚洲国产99在线精品一区69堂 | 青青草在线播放 | 免费观看的毛片 | 色中文网| 思思91精品国产综合在线 |