一個被阻止的線程可以通過兩種方式被提前釋放:
釋放一個線程的鎖必須通過另外活動的線程實現,等待的線程自己是不能對它的被阻止狀態做任何事情。
Interrupt方法
在一個被阻止的線程上調用Interrupt 方法,將強制釋放它,同時拋出ThreadInterruptedException異常,如下:
class Program { static void Main() { Thread t = new Thread (delegate() { try { Thread.Sleep (Timeout.Infinite); } catch (ThreadInterruptedException) { Console.Write ("Forcibly "); } Console.WriteLine ("Woken!"); }); t.Start(); t.Interrupt(); } } Output: Forcibly Woken!
中斷一個線程僅僅釋放它的當前的(或下一個)等待狀態,並不結束這個線程(當然,除非未處理ThreadInterruptedException異常)。
如果Interrupt被一個未阻止的線程調用,那麼線程將繼續執行直到下一次被阻止時,它拋出ThreadInterruptedException異常。用下面的測試避免這個問題,不過這不是一個線程安全的方式。
if ((worker.ThreadState & ThreadState.WaitSleepJoin) > 0) worker.Interrupt();
隨意中斷線程有很大風險,因為任何框架或第三方方法在調用堆棧時都可能意外地在已訂閱的代碼上收到中斷。如果這個方法沒有被設計成可以被中斷(沒有適當處理finally塊)的對象,可能剩下無用的狀態,或資源釋放不完全。如果確切知道應該在哪兒中斷,中斷一個線程也是安全的,比如信號系統。
Abort方法
被阻止的線程也可以通過Abort方法被強制釋放,除了用ThreadAbortException異常代替了ThreadInterruptedException異常,與調用Interrupt相似。異常將被拋出在catch裡,直到Thread.ResetAbort在catch中被調用,在這期間線程的ThreadState為AbortRequested。
Interrupt 與 Abort 之間最大不同在於它們調用一個非阻止線程所發生的事情。Interrupt繼續工作直到下一次阻止發生,Abort在線程當前所執行的位置(可能甚至不在你的代碼中)拋出異常。終止一個非阻止的線程會帶來嚴重的後果。