中斷是給線程的一個訓示,告訴它應該停止正在做的事并去做其他事情。一個線程究竟要怎麼響應中斷請求取決于程式員,不過讓其終止是很普遍的做法。這是本文重點強調的用法。
一個線程通過調用對被中斷線程的thread對象的interrupt()方法,發送中斷信号。為了讓中斷機制正常工作,被中斷的線程必須支援它自己的中斷(即要自己進行中斷)
線程如何支援自身的中斷?這取決于它目前正在做什麼。如果線程正在頻繁調用會抛interruptedexception異常的方法,在捕獲異常之後,它隻是從run()方法中傳回。例如,假設在sleepmessages的例子中,關鍵的消息循環線上程的runnable對象的run方法中,代碼可能會被修改成下面這樣以支援中斷:
<code>01</code>
<code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i < importantinfo.length; i++) {</code>
<code>02</code>
<code> </code><code>// pause for 4 seconds</code>
<code>03</code>
<code> </code><code>try</code> <code>{</code>
<code>04</code>
<code> </code><code>thread.sleep(</code><code>4000</code><code>);</code>
<code>05</code>
<code> </code><code>}</code><code>catch</code> <code>(interruptedexception e) {</code>
<code>06</code>
<code> </code><code>// we've been interrupted: no more messages.</code>
<code>07</code>
<code> </code><code>return</code><code>;</code>
<code>08</code>
<code> </code><code>}</code>
<code>09</code>
<code> </code><code>// print a message</code>
<code>10</code>
<code> </code><code>system.out.println(importantinfo[i]);</code>
<code>11</code>
<code>}</code>
許多會抛interruptedexception異常的方法(如sleep()),被設計成接收到中斷後取消它們目前的操作,并在立即傳回。
如果一個線程長時間運作而不調用會抛interruptedexception異常的方法會怎樣? 那它必須周期性地調用thread.interrupted()方法,該方法在接收到中斷請求後傳回true。例如:
<code>1</code>
<code>for</code> <code>(</code><code>int</code> <code>i =</code><code>0</code><code>; i < inputs.length; i++) {</code>
<code>2</code>
<code> </code><code>heavycrunch(inputs[i]);</code>
<code>3</code>
<code> </code><code>if</code> <code>(thread.interrupted()) {</code>
<code>4</code>
<code> </code><code>// we've been interrupted: no more crunching.</code>
<code>5</code>
<code> </code><code>return</code><code>;</code>
<code>6</code>
<code> </code><code>}</code>
<code>7</code>
在這個簡單的例子中,代碼隻是檢測中斷,并在收到中斷後退出線程。在更複雜的應用中,抛出一個interruptedexception異常可能更有意義。
<code>if</code> <code>(thread.interrupted()){</code>
<code> </code><code>throw</code> <code>new</code> <code>interruptedexception();</code>
這使得中斷處理代碼能集中在catch語句中。
中斷機制通過使用稱為中斷狀态的内部标記來實作。調用thread.interrupt()設定這個标記。當線程通過調用靜态方法thread.interrupted()檢測中斷時,中斷狀态會被清除。非靜态的isinterrupted()方法被線程用來檢測其他線程的中斷狀态,不改變中斷狀态标記。
按照慣例,任何通過抛出一個interruptedexception異常退出的方法,當抛該異常時會清除中斷狀态。不過,通過其他的線程調用interrupt()方法,中斷狀态總是有可能會立即被重新設定。