java執行緒學習(三):執行緒中斷 interrupt() 方法的使用
阿新 • • 發佈:2018-12-18
上一章節中,我們對執行緒終止stop方法進行了講解,stop終止執行緒的方法已經被丟棄,原因是執行緒的終止太暴力,會導致不必要的資料錯誤,所以stop方法在不自信的情況下,慎用慎用。。。。同時,也提供了較為完善的終止方案了。
本節就來學習執行緒中斷 interrupt() 方法的使用:
一、先來看看原始碼:
public void interrupt() { if (this != currentThread()) { this.checkAccess(); } Object var1 = this.blockerLock; synchronized (this.blockerLock) { Interruptible var2 = this.blocker; if (var2 != null) { this.interrupt0(); var2.interrupt(this); return; } } this.interrupt0(); } public static boolean interrupted() { return currentThread().isInterrupted(true); } public boolean isInterrupted() { return this.isInterrupted(false); }
可以看出目前跟中斷相關的有三個方法,分別是:
- interrupt(): 例項方法。它通知目標執行緒中斷,也就是設定中斷標誌位(中斷標誌位表示當前執行緒已經被中斷了)。
- isInterrupted():例項方法。用來判斷當前執行緒是否有被中斷(通過檢查中斷標誌位)
- interrupted():靜態方法。用來判斷當前執行緒的中斷狀態,並清除當前執行緒的中斷標誌為狀態。
二、我們來看看這些例子加理解:
栗子一:只使用interrupt()方法:
public class Interrupt_demo { /** * 例子1: * 只使用interrupt方法 * @author fei * */ public static class Interrupt_demo1 extends Thread{ @Override public void run() { System.out.println("執行緒"+Thread.currentThread().getName()+"在執行~~~~"); Thread.yield(); } } public static void main(String[] args) { //建立10條執行緒 for (int i = 0; i < 10; i++) { Thread thread=new Interrupt_demo1(); thread.start(); //如果是偶數,那麼就中斷 if (i%2==0) { thread.interrupt(); } } } }
建立10條執行緒,當偶數次的時候,中斷該執行緒的執行,打印出該資訊:
明顯看到,就算中斷了,也一樣會執行10條執行緒。說明單單使用這個interrupt()方法是沒有什麼效果的。
栗子二:使用interrupt()配合isInterrupted()方法:
package stop_demo; public class Interrupt_demo { /** * 例子1: * 只使用interrupt方法 * @author fei * */ public static class Interrupt_demo1 extends Thread{ @Override public void run() { //相對慄一新增對執行緒是否中斷進行判斷 if (Thread.currentThread().isInterrupted()) { System.out.println("執行緒"+Thread.currentThread().getName()+"已被中斷!!"); return; } System.out.println("執行緒"+Thread.currentThread().getName()+"在執行~~~~"); Thread.yield(); } } public static void main(String[] args) { //建立10條執行緒 for (int i = 0; i < 10; i++) { Thread thread=new Interrupt_demo1(); thread.start(); //如果是偶數,那麼就中斷 if (i%2==0) { thread.interrupt(); } } } }
執行後輸出:
可以看到,使用interrupt()配合isInterrupted()方法是可以達到中斷執行緒的目的的,這就理解interrupt()方法設定標誌位的含義了。同時也可以看出,isInterrupted()方法實際上和上一篇文章stopThread()方法類似,但是isInterrupted()更為好用,因為isInterrupted()可以用在迴圈體中,有wait和sleep操作的執行緒中。
栗子三:三個方法配合使用
package stop_demo;
public class Interrupt_demo {
/**
* 例子1:
* 只使用interrupt方法
* @author fei
*
*/
public static class Interrupt_demo1 extends Thread{
@Override
public void run() {
if (Thread.interrupted()) {
System.out.println("執行緒"+Thread.currentThread().getName()+"判斷為中斷,但已經清除中斷");
//看是否進入該判斷,如果不進入那麼證明中斷已經清除了
if (Thread.currentThread().isInterrupted()) {
System.out.println("執行緒"+Thread.currentThread().getName()+"已被中斷!!");
return;
}
}
System.out.println("執行緒"+Thread.currentThread().getName()+"在執行~~~~");
Thread.yield();
}
}
public static void main(String[] args) {
//建立10條執行緒
for (int i = 0; i < 10; i++) {
Thread thread=new Interrupt_demo1();
thread.start();
//如果是偶數,那麼就中斷
if (i%2==0) {
thread.interrupt();
}
}
}
}
執行後輸出:
可以看到,使用靜態方法判斷中斷執行緒,清除後,該執行緒就不是中斷狀態了,所以
if (Thread.currentThread().isInterrupted()) {
System.out.println("執行緒"+Thread.currentThread().getName()+"已被中斷!!");
return;
}
該方法就不會執行了。