自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

我們該如何正確的中斷一個正在執(zhí)行的線程??

網(wǎng)絡(luò) 通信技術(shù)
作者個人研發(fā)的在高并發(fā)場景下,提供的簡單、穩(wěn)定、可擴(kuò)展的延遲消息隊列框架,具有精準(zhǔn)的定時任務(wù)和延遲隊列處理功能。

[[358852]]

作者個人研發(fā)的在高并發(fā)場景下,提供的簡單、穩(wěn)定、可擴(kuò)展的延遲消息隊列框架,具有精準(zhǔn)的定時任務(wù)和延遲隊列處理功能。自開源半年多以來,已成功為十幾家中小型企業(yè)提供了精準(zhǔn)定時調(diào)度方案,經(jīng)受住了生產(chǎn)環(huán)境的考驗。為使更多童鞋受益,現(xiàn)給出開源框架地址:https://github.com/sunshinelyz/mykit-delay

 寫在前面

當(dāng)我們在調(diào)用Java對象的wait()方法或者線程的sleep()方法時,需要捕獲并處理InterruptedException異常。如果我們對InterruptedException異常處理不當(dāng),則會發(fā)生我們意想不到的后果!今天,我們就以一個案例的形式,來為大家詳細(xì)介紹下為何中斷執(zhí)行的線程不起作用。

程序案例

例如,下面的程序代碼,InterruptedTask類實現(xiàn)了Runnable接口,在run()方法中,獲取當(dāng)前線程的句柄,并在while(true)循環(huán)中,通過isInterrupted()方法來檢測當(dāng)前線程是否被中斷,如果當(dāng)前線程被中斷就退出while(true)循環(huán),同時,在while(true)循環(huán)中,還有一行Thread.sleep(100)代碼,并捕獲了InterruptedException異常。整個代碼如下所示。

  1. package io.binghe.concurrent.lab08; 
  2.  
  3. /** 
  4.  * @author binghe 
  5.  * @version 1.0.0 
  6.  * @description 線程測試中斷 
  7.  */ 
  8. public class InterruptedTask implements Runnable{ 
  9.  
  10.     @Override 
  11.     public void run() { 
  12.  
  13.         Thread currentThread = Thread.currentThread(); 
  14.         while (true){ 
  15.             if(currentThread.isInterrupted()){ 
  16.                 break; 
  17.             } 
  18.  
  19.             try { 
  20.                 Thread.sleep(100); 
  21.             } catch (InterruptedException e) { 
  22.                 e.printStackTrace(); 
  23.             } 
  24.         } 
  25.     } 

上述代碼的本意是通過isInterrupted()方法檢查線程是否被中斷了,如果中斷了就退出while循環(huán)。其他線程通過調(diào)用執(zhí)行線程的interrupt()方法來中斷執(zhí)行線程,此時會設(shè)置執(zhí)行線程的中斷標(biāo)志位,從而使currentThread.isInterrupted()返回true,這樣就能夠退出while循環(huán)。

這看上去沒啥問題啊!但真的是這樣嗎?我們創(chuàng)建一個InterruptedTest類用于測試,代碼如下所示。

  1. package io.binghe.concurrent.lab08; 
  2.  
  3. /** 
  4.  * @author binghe 
  5.  * @version 1.0.0 
  6.  * @description 測試線程中斷 
  7.  */ 
  8. public class InterruptedTest { 
  9.     public static void main(String[] args){ 
  10.         InterruptedTask interruptedTask = new InterruptedTask(); 
  11.         Thread interruptedThread = new Thread(interruptedTask); 
  12.         interruptedThread.start(); 
  13.         try { 
  14.             Thread.sleep(1000); 
  15.         } catch (InterruptedException e) { 
  16.             e.printStackTrace(); 
  17.         } 
  18.         interruptedThread.interrupt(); 
  19.     } 

我們運行main方法,如下所示。

這竟然跟我們想象的不一樣!不一樣!不一樣!這是為什么呢?

問題分析

上述代碼明明調(diào)用了線程的interrupt()方法來中斷線程,但是卻并沒有起到啥作用。原因是線程的run()方法在執(zhí)行的時候,大部分時間都是阻塞在sleep(100)上,當(dāng)其他線程通過調(diào)用執(zhí)行線程的interrupt()方法來中斷執(zhí)行線程時,大概率的會觸發(fā)InterruptedException異常,在觸發(fā)InterruptedException異常的同時,JVM會同時把線程的中斷標(biāo)志位清除,所以,這個時候在run()方法中判斷的currentThread.isInterrupted()會返回false,也就不會退出當(dāng)前while循環(huán)了。

既然問題分析清楚了,那如何中斷線程并退出程序呢?

問題解決

正確的處理方式應(yīng)該是在InterruptedTask類中的run()方法中的while(true)循環(huán)中捕獲異常之后重新設(shè)置中斷標(biāo)志位,所以,正確的InterruptedTask類的代碼如下所示。

  1. package io.binghe.concurrent.lab08; 
  2.  
  3. /** 
  4.  * @author binghe 
  5.  * @version 1.0.0 
  6.  * @description 中斷線程測試 
  7.  */ 
  8. public class InterruptedTask implements Runnable{ 
  9.  
  10.     @Override 
  11.     public void run() { 
  12.  
  13.         Thread currentThread = Thread.currentThread(); 
  14.         while (true){ 
  15.             if(currentThread.isInterrupted()){ 
  16.                 break; 
  17.             } 
  18.  
  19.             try { 
  20.                 Thread.sleep(100); 
  21.             } catch (InterruptedException e) { 
  22.                 e.printStackTrace(); 
  23.                 currentThread.interrupt(); 
  24.             } 
  25.         } 
  26.     } 

可以看到,我們在捕獲InterruptedException異常的catch代碼塊中新增了一行代碼。

  1. currentThread.interrupt(); 

這就使得我們捕獲到InterruptedException異常后,能夠重新設(shè)置線程的中斷標(biāo)志位,從而中斷當(dāng)前執(zhí)行的線程。

我們再次運行InterruptedTest類的main方法,如下所示。

總結(jié)

處理InterruptedException異常時要小心,如果在調(diào)用執(zhí)行線程的interrupt()方法中斷執(zhí)行線程時,拋出了InterruptedException異常,則在觸發(fā)InterruptedException異常的同時,JVM會同時把執(zhí)行線程的中斷標(biāo)志位清除,此時調(diào)用執(zhí)行線程的isInterrupted()方法時,會返回false。此時,正確的處理方式是在執(zhí)行線程的run()方法中捕獲到InterruptedException異常,并重新設(shè)置中斷標(biāo)志位(也就是在捕獲InterruptedException異常的catch代碼塊中,重新調(diào)用當(dāng)前線程的interrupt()方法)。

本文轉(zhuǎn)載自微信公眾號「冰河技術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系冰河技術(shù)公眾號。

 

責(zé)任編輯:武曉燕 來源: 冰河技術(shù)
相關(guān)推薦

2018-06-28 08:41:37

2014-07-02 10:03:42

App推廣渠道

2020-06-01 11:01:28

智慧城市物聯(lián)網(wǎng)技術(shù)

2016-09-30 09:49:05

2021-11-03 12:34:41

黑客網(wǎng)絡(luò)釣魚攻擊

2024-11-21 08:31:07

耗資源神秘進(jìn)程

2020-06-20 14:15:53

信息安全數(shù)據(jù)技術(shù)

2025-01-26 09:35:45

2018-03-07 11:00:27

2021-10-27 06:49:34

線程池Core函數(shù)

2010-09-09 21:34:06

2021-11-15 10:35:46

Python線程代碼

2022-03-09 09:43:01

工具類線程項目

2021-02-03 10:34:35

多云云安全CISO

2023-02-01 16:36:31

GNOMEChatGPTLinux

2024-03-25 12:30:05

AI模型

2010-04-01 09:18:38

云計算

2014-11-28 09:45:35

程序員

2010-02-23 15:52:14

Python編輯器

2017-02-06 10:30:13

iOS表單正確姿勢
點贊
收藏

51CTO技術(shù)棧公眾號