成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何優雅的「打斷」你的線程?

開發 開發工具
目前在 Tomcat 使用中,無法在運行時直接操作 Connector ,所以一般情況這個 pause 標識可能沒法設置,但有幾種觸發的方式。

最近看了點 psi-Probe的源代碼,在線程列表頁面,可以對頁面中各個進行線程管理,其中有這樣一個操作,見最左側藍色方框:

點擊每個線程對應的箭頭按鈕,會彈出下方的提示:

實際這上按鈕的操作,是要 「Kill」這個指定的線程。

順著鏈接,我們能看到,具體的實現是這個樣子:

  1. String threadName = ServletRequestUtils.getStringParameter(request, "thread", null); 
  2.  
  3. Thread thread = null
  4. if (threadName != null) { 
  5.   thread = Utils.getThreadByName(threadName); 
  6.  
  7. if (thread != null) { 
  8.   thread.stop(); 

正如前面的彈窗提示,這里果然調用的是個危險操作:

  1. Thread.stop() 

這里的 「stop」方法,和「resume」方法、「suspend」方法并稱 Thread 三少,因為線程安全問題,都已經被 @Deprecated 了。

官方文檔說的好:

Stopping a thread causes it to unlock all the monitors that it has locked

當我們停止一個線程時,它會悄悄的把所持有的 monitor 鎖釋放了,此時,其他依賴鎖的線程可能就會搶到鎖執行。關鍵此時,當前 stop 的線程實際并沒有處理完所有先決條件,可能這個時候就產生了詭異的問題,加班的日子可能就悄悄來了。

那你說 「Stop 不讓用了,總得讓我們有辦法處理線程吧,哪怕通知他,打斷他一下,讓他停止」。

目前有以下幾種方式來實現。

異常

這點 Thread 也想到了,提供了一個「異常」來達到這個打斷的目的。這個異常在其他線程要打斷某個特定線程時執行,如果是符合條件,會拋出來。此時這個特定線程自行根據這次打斷來判斷后續是不是要再執行線程內的邏輯,還是直接跳出處理。

這個異常就是 InterruptedException。一般使用方式類似這樣

  1. try { 
  2.     Thread.sleep(backgroundProcessorDelay * 1000L); 
  3. } catch (InterruptedException e) { 
  4.     // 具體在中斷通知后的操作 
  5.      
  6.  xxxThread.interrupt();   

目前有以下方法能夠進行這種操作

  • Thread.sleep
  • Thread.join
  • Object.wait

以wait方法為例,我們來看文檔里的描述

  1. * @throws  InterruptedException if any thread interrupted the 
  2. *             current thread before or while the current thread 
  3. *             was waiting for a notification.  The <i>interrupted 
  4. *             status</i> of the current thread is cleared when 
  5. *             this exception is thrown. 

這里有一點信息: 「interrupted status」,這個是個狀態標識,在Thread類中,可以通過 isInterrupted來判斷當前線程是否被中斷。這個標識也可以用來作為一個退出線程執行的標識來直接使用。 但例外是阻塞方法在收到中斷方法調用后,這個標識會被清除重置,所以需要注意下。

我們在執行阻塞方法線程的interrupt方法時,此時并不能拿到這個標識。

另外,拿到異常時,需要關注,如果是類似于后臺循環執行的調度線程,在收到中斷異常時需要處理異常再 break 才能跳出,否則只是相當于一個空操作。

目前一些程序里用這種的倒不多,用下面這種的多一些。

退出標識

對于一些長駐線程,會在某些時候需要退出執行,這種情況下,常采用的操作類似這樣, 以Tomcat 的NioConnector 里的Acceptor為例:

  1. protected class Acceptor extends AbstractEndpoint.Acceptor { 
  2.  
  3.     @Override 
  4.     public void run() { 
  5.  
  6.         int errorDelay = 0
  7.  
  8.         // Loop until we receive a shutdown command 
  9.         while (running) {   // 標識1 
  10.  
  11.             // Loop if endpoint is paused 
  12.             while (paused && running) {   // 標識2 
  13.                 state = AcceptorState.PAUSED; 
  14.                 try { 
  15.                     Thread.sleep(50); 
  16.                 } catch (InterruptedException e) { 
  17.                     // Ignore 
  18.                 } 
  19.             } 
  20.  
  21.             if (!running) { 
  22.                 break; 
  23.             } 
  24.             ... 
  25.         }     

用這種退出標識時,記得一定要聲明為 volatile ,類似這樣:

  1. /** 
  2.  * Running state of the endpoint. 
  3.  */ 
  4. protected volatile boolean running = false
  5.  
  6.  
  7. /** 
  8.  * Will be set to true whenever the endpoint is paused. 
  9.  */ 
  10. protected volatile boolean paused = false

否則因為多線程的可見性問題, 這個線程可能一直都不會退出。

目前在 Tomcat 使用中,無法在運行時直接操作 Connector ,所以一般情況這個 pause 標識可能沒法設置。但有幾種觸發的方式,一種是通過 JConsole 等工具連接到 MBeanServer 上,直接通過其MBean方法操作pause,來改變值,另一種是使用類似 psi-Probe(一款功能強大的Tomcat 管理監控工具)這種管理控制臺,之前我已經把可以操作 Connector 狀態的代碼提交給 github上(怎樣參與到全世界優秀的開源項目中?),commiter 已經合入。可以使用進行狀態改變觀察。

總體來說,如果處理sleep/wait等操作,擔心時間太長,可以通過 interrupt 來進行,對于駐留線程,可以通過退出標識來處理。

【本文為51CTO專欄作者“侯樹成”的原創稿件,轉載請通過作者微信公眾號『Tomcat那些事兒』獲取授權】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2018-07-12 14:20:33

SQLSQL查詢編寫

2025-06-24 08:25:00

Java并發編程線程

2025-01-26 09:35:45

2024-11-13 16:37:00

Java線程池

2015-11-26 10:53:45

LinuxWindowsMac OS

2021-01-19 10:35:49

JVM場景函數

2017-07-26 11:32:50

NETRabbitMQ系統集成

2021-12-15 23:10:34

JS Debugger 前端開發

2023-05-12 14:14:00

Java線程中斷

2019-09-29 16:17:25

Java代碼性能編程語言

2022-09-08 08:03:30

RocketMQ線程技巧

2024-09-26 10:51:51

2020-03-27 11:41:12

線程 Java中止

2020-10-16 11:48:06

服務器系統運維

2017-06-23 15:45:09

AndroidThread

2022-06-07 08:59:58

hookuseRequestReact 項目

2023-10-10 13:23:18

空指針異常Java

2023-10-19 19:42:25

IstioPodkubernetes

2020-08-26 07:17:19

通信

2022-09-09 15:17:02

CentOS 7Linux
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一区二区三区在线观看免费 | 久久精品日产第一区二区三区 | 成人免费观看视频 | 亚洲欧美一区二区在线观看 | 欧美精品在线免费 | 久久精品美女 | 国产精品久久久久久久久久 | 波多野结衣亚洲 | 国产成人在线免费 | 中文字幕视频网 | 日韩在线电影 | 国产精品成人一区二区三区夜夜夜 | 一区二区三区中文字幕 | www.日韩| 欧区一欧区二欧区三免费 | 欧美性区 | 久久国产亚洲 | 成人亚洲片| 成人免费网站 | 日韩欧美福利视频 | 成人在线不卡 | 99精品欧美一区二区蜜桃免费 | 免费三级av | 欧美激情在线一区二区三区 | 99精品一区二区三区 | 中文字幕日韩在线观看 | www.亚洲精品 | 91在线免费视频 | 欧美一级黄色网 | 91精品国产综合久久久久蜜臀 | 超碰在线人人 | 三级视频在线观看电影 | 欧美精品一区二区三区在线 | 亚洲精品在线国产 | 国产在线永久免费 | 国产精品一区二区在线 | 久久99视频 | 中文字幕在线一区 | 国产成人99久久亚洲综合精品 | 日韩欧美在线视频 | 久久精品一区 |