天天看點

Oracle官方并發教程之中斷

中斷是給線程的一個訓示,告訴它應該停止正在做的事并去做其他事情。一個線程究竟要怎麼響應中斷請求取決于程式員,不過讓其終止是很普遍的做法。這是本文重點強調的用法。

一個線程通過調用對被中斷線程的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 &lt; 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 &lt; 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()方法,中斷狀态總是有可能會立即被重新設定。 

繼續閱讀