09之 interrupt()和線程終止方式

interrupt()是給線程設(shè)置中斷標(biāo)志;interrupted()是檢測中斷并清除中斷狀態(tài);isInterrupted()只檢測中斷。還有重要的一點(diǎn)就是interrupted()作用于當(dāng)前線程,interrupt()和isInterrupted()作用于此線程,即代碼中調(diào)用此方法的實(shí)例所代表的線程。

————————————————

原文鏈接:https://blog.csdn.net/qq_39682377/article/details/81449451



首先看看官方說明:

interrupt()方法

其作用是中斷此線程(此線程不一定是當(dāng)前線程,而是指調(diào)用該方法的Thread實(shí)例所代表的線程),但實(shí)際上只是給線程設(shè)置一個中斷標(biāo)志,線程仍會繼續(xù)運(yùn)行。


interrupted()方法

作用是測試當(dāng)前線程是否被中斷(檢查中斷標(biāo)志),返回一個boolean并清除中斷狀態(tài),第二次再調(diào)用時中斷狀態(tài)已經(jīng)被清除,將返回一個false。


isInterrupted()方法

作用是只測試此線程是否被中斷 ,不清除中斷狀態(tài)。


下面我們進(jìn)行測試說明:

定義一個MyThread類,繼承Thread,如下:

public class MyThread extends Thread {

? ? @Override

? ? public? void run() {

? ? ? ? for (int i = 0; i < 10; i++) {

? ? ? ? ? ? System.out.println("i="+(i+1));

? ? ? ? }

? ? }

}

在main方法中測試:

public class Do {

public static void main(String[] args ) {

MyThread thread=new MyThread();

thread.start();

thread.interrupt();

System.out.println("第一次調(diào)用thread.isInterrupted():"+thread.isInterrupted());

System.out.println("第二次調(diào)用thread.isInterrupted():"+thread.isInterrupted());

System.out.println("thread是否存活:"+thread.isAlive());

}

}

輸出如下:

從結(jié)果可以看出調(diào)用interrupt()方法后,線程仍在繼續(xù)運(yùn)行,并未停止,但已經(jīng)給線程設(shè)置了中斷標(biāo)志,兩個isInterrupted()方法都會輸出true,也說明isInterrupted()方法并不會清除中斷狀態(tài)。

下面我們把代碼修改一下,多加兩行調(diào)用interrupted()方法:

public class Do {

public static void main(String[] args ) {

MyThread thread=new MyThread();

thread.start();

thread.interrupt();

System.out.println("第一次調(diào)用thread.isInterrupted():"+thread.isInterrupted());

System.out.println("第二次調(diào)用thread.isInterrupted():"+thread.isInterrupted());

? ? ? ? ? ? ? ? ? ? //測試interrupted()函數(shù)

System.out.println("第一次調(diào)用thread.interrupted():"+thread.interrupted());

System.out.println("第二次調(diào)用thread.interrupted():"+thread.interrupted());

System.out.println("thread是否存活:"+thread.isAlive());

}

}

輸出如下:

從輸出結(jié)果看,可能會有疑惑,為什么后面兩個interrupted方法輸出的都是false,而不是預(yù)料中的一個true一個false?注意?。?!這是一個坑?。?!上面說到,interrupted()方法測試的是當(dāng)前線程是否被中斷,當(dāng)前線程?。?!當(dāng)前線程?。?!這里當(dāng)前線程是main線程,而thread.interrupt()中斷的是thread線程,這里的此線程就是thread線程。所以當(dāng)前線程main從未被中斷過,盡管interrupted()方法是以thread.interrupted()的形式被調(diào)用,但它檢測的仍然是main線程而不是檢測thread線程,所以thread.interrupted()在這里相當(dāng)于main.interrupted()。對于這點(diǎn),下面我們再修改進(jìn)行測試。

Thread.currentThread()函數(shù)可以獲取當(dāng)前線程,下面代碼中獲取的是main線程

public class Do {

public static void main(String[] args ) throws InterruptedException {

Thread.currentThread().interrupt();

System.out.println("第一次調(diào)用Thread.currentThread().interrupt():"

+Thread.currentThread().isInterrupted());

System.out.println("第一次調(diào)用thread.interrupted():"

+Thread.currentThread().interrupted());

System.out.println("第二次調(diào)用thread.interrupted():"

+Thread.currentThread().interrupted());

}

}

這里都是針對當(dāng)前線程在操作,如果interrupted()方法有檢測中斷并清除中斷狀態(tài)的作用,預(yù)料中的輸出應(yīng)該是true-true-false,實(shí)際輸出如下:

結(jié)果證明猜想是正確的。

若果想要是實(shí)現(xiàn)調(diào)用interrupt()方法真正的終止線程,則可以在線程的run方法中做處理即可,比如直接跳出run()方法使線程結(jié)束,視具體情況而定,下面是一個例子。

修改MyThread類:

public class MyThread extends Thread {

? ? @Override

? ? public? void run() {

? ? ? ? for (int i = 0; i < 1000; i++) {

? ? ? ? ? ? System.out.println("i="+(i+1));

? ? ? ? ? ? if(this.isInterrupted()){

? ? ? ? ? ? ? ? System.out.println("通過this.isInterrupted()檢測到中斷");

? ? ? ? ? ? ? ? System.out.println("第一個interrupted()"+this.interrupted());

? ? ? ? ? ? ? ? System.out.println("第二個interrupted()"+this.interrupted());

? ? ? ? ? ? ? ? break;

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? System.out.println("因?yàn)闄z測到中斷,所以跳出循環(huán),線程到這里結(jié)束,因?yàn)楹竺鏇]有內(nèi)容了");

? ? }

}

測試MyThread:

public class Do {

public static void main(String[] args ) throws InterruptedException {

MyThread myThread=new MyThread();

myThread.start();

myThread.interrupt();

//sleep等待一秒,等myThread運(yùn)行完

Thread.currentThread().sleep(1000);

System.out.println("myThread線程是否存活:"+myThread.isAlive());

}

}

結(jié)果:

最后總結(jié),關(guān)于這三個方法,interrupt()是給線程設(shè)置中斷標(biāo)志;interrupted()是檢測中斷并清除中斷狀態(tài);isInterrupted()只檢測中斷。還有重要的一點(diǎn)就是interrupted()作用于當(dāng)前線程,interrupt()和isInterrupted()作用于此線程,即代碼中調(diào)用此方法的實(shí)例所代表的線程。

————————————————

版權(quán)聲明:本文為CSDN博主「LZing_」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/qq_39682377/article/details/81449451

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容