雜談 執行緒中斷 Interrupt

2022-04-07 01:59:40 字數 2551 閱讀 2337

以前有乙個錯誤的認識,以為中斷操作都會丟擲異常,後來才發現並不是這樣,所以今天就來做乙個關於中斷的總結。

已被棄用的stop方法

早期,thread類中有乙個stop方法,用於強行關閉乙個執行緒。但是後來發現此操作並不安全,強行關閉可能導致一致性問題。故stop方法已被官方棄用。具體原因請看why are thread.stop, thread.suspend and thread.resume deprecated?.。

既然,stop方法不能用了,我們就要另闢蹊徑。而我們知道,只要執行緒的run方法"完成",底層作業系統的執行緒就會被釋放。"完成"意味著,run方法結束,而結束的方式有兩種,一種是丟擲異常,另一種則是方法返回。所以,我們要做的就是控制線程任務,丟擲異常或返回(return)。

flag機制

前面說到對執行緒任務的執行進行控制,而執行緒任務一旦跑起來,又如何對其執**況進行干預呢?答案就是,讓**反覆檢查某個值的狀態,如果達到某個狀態,就結束執行(return)或者丟擲異常。而這個值,可以被外部訪問到,使用者可以在需要的時候設定"結束flag"。

例如:

class task implements

runnable

public

void

run()

system.out.println("i'm stopped.");

}}public

class

main

}

強制結束執行緒被取消,取而代之的,是一種協作機制,即中斷機制。也就是說,乙個執行緒只能向另乙個執行緒傳送中斷訊號,而不能強行對其進行關閉。而另乙個執行緒如何處理,就得看其正在執行的**對中斷訊號如何反應了。其實就是前面說的flag機制,但是,其內部維護flag,還有額外的和阻塞庫互動的內容。例子如下:

class task implements

runnable

system.out.println("i'm stopped.");

}}public

class

main

}

其中,thread.currentthread()靜態方法將獲得當前執行此段**的執行緒物件。然後呼叫interrupted()方法獲取執行緒中斷狀態,如果執行緒被中斷,則返回true。執行緒的中斷狀態可以用interrupt()方法設定。

下面提一下中斷可能產生讓人產生疑惑的幾個方法:

要想查明原因,最好的方法就是檢視原始碼。我們先來看看interrupt**

由上述關聯方法可知,本地方法的實現依賴於jvm實現。下面內容以hospot虛擬機器為例。以下來自hotspot原始碼\src\share\vm\prims\jvm.cpp

前面只是做一些狀態檢查,最主要的是呼叫thread::interrupt函式。以下來自hospot原始碼\src\share\vm\runtime\thread.cpp

此處呼叫os,即作業系統的中斷方法。以下來自hospot原始碼\src\os\linux\vm\os_linux.cpp

以上主要進行了兩個操作,乙個設定中斷狀態,乙個是喚醒當前執行緒(如果當前執行緒處於掛起狀態)。

為何需要喚醒執行緒?

前面已經說了,中斷跟flag機制差不多,不會實際上關閉執行緒。要想關閉執行緒,必須讓執行緒方法返回或者丟擲異常。如果不喚醒執行緒,則**也就不會被執行。任務會一直處於無法完成的狀態。

如果wait或sleep方法被中斷,會丟擲中斷異常。這就是前面說的與阻塞庫的互動內容。但是我們已經看到,中斷操作實際上只是設定了中斷狀態,和喚醒執行緒。那麼異常丟擲又是在**實現的呢?而且wait和sleep方法同樣是本地方法,那沒辦法了,只能再看原始碼,以下以sleep方法為例。以下來自hotspot原始碼\src\share\vm\prims\jvm.cpp

再來看看os::sleep裡面是如何處理的。以下來自hotspot原始碼\src\os\linux\vm\os_linux.cpp

由以上**可知,sleep函式會將執行緒掛起,然後**卡死在掛起操作上,然後其他執行緒中斷了此執行緒,此執行緒被喚醒,然後sleep函式繼續執行,檢查中斷狀態,如果已中斷,則丟擲中斷異常。

執行緒中斷interrupt

案例 這裡需要注意一下,try catch到interruptedexception e異常時,中斷訊號會被抹除,所以th.isinterrupted 如果執行在catch異常前,則isinterrupted為true,可以正常退出,否則中斷訊號抹除後,isinterrupted得到的值為false...

中斷執行緒 interrupt

呼叫interrupt 通知執行緒應該中斷 1 如果執行緒處於阻塞狀態,則執行緒立即退出被阻塞狀態,並丟擲乙個interruptedexception異常 2 如果執行緒處於正常活動狀態,那 package com.mall.controllor.alene import sun.managemen...

Java 多執行緒 interrupt 中斷

當乙個執行緒執行時,另乙個執行緒可以呼叫對應的thread物件的interrupt 方法來中斷它,該方法只是在目標執行緒中設定乙個標誌,表示它已經被中斷,並立即返回。這裡需要注意的是,如果只是單純的呼叫interrupt 方法,執行緒並沒有實際被中斷,會繼續往下執行。created by yangt...