更新時(shí)間:2020-11-20 17:45:39 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1845次
Java中提供了shop()方法來中斷線程,但由于該方法過于暴力而被定義為過期方法。假如一條線程在修改一段數(shù)據(jù)時(shí),且已經(jīng)修改了一半,此時(shí)的你強(qiáng)行用shop()方法中斷該線程后,數(shù)據(jù)處于一半修改過、一半未修改的狀態(tài),該數(shù)據(jù)就已經(jīng)廢了(且不會(huì)有任何提示)。于是,在Java中采用了新的interrupt方法來完成Java多線程中斷機(jī)制。
Thread類定義了如下關(guān)于中斷的方法:

線程對中斷的反應(yīng)
1.RUNNABLE:線程在運(yùn)行或具備運(yùn)行條件只是在等待操作系統(tǒng)調(diào)度
2.WAITING/TIMED_WAITING:線程在等待某個(gè)條件或超時(shí)
3.BLOCKED:線程在等待鎖,試圖進(jìn)入同步塊
4.NEW/TERMINATED:線程還未啟動(dòng)或已結(jié)束
public void Thread.interrupt() //中斷線程
public boolean Thread.isInterrupted() //判斷是否被中斷
public static boolean Thread.interrupted() //判斷是否被中斷,且清除當(dāng)前中斷狀態(tài)
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread() {
@Override
public void run () {
while (true) {
Thread.yield();
}
}
};
t1.start();
Thread.sleep(2000);
ti.interrupt();
}
在這里雖然調(diào)用了interrupt()方法,但該線程并不會(huì)停下。因?yàn)樵摲椒ㄖ皇窃O(shè)置了一個(gè)中斷狀態(tài),但該線程并未對此中斷狀態(tài)做出反應(yīng)。
以下代碼進(jìn)行了對中斷狀態(tài)的處理。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread() {
@Override
public void run () {
while (true) {
if (Thread.currentThread().isInterrupted()){ //此方法返回中斷狀態(tài),且不會(huì)清除該中斷狀態(tài)。
System.out.println("Interruted!");
breadk;
}
Thread.yield();
}
}
};
t1.start();
Thread.sleep(2000);
ti.interrupt();
}
但我們使用wait() 或者 sleep() 方法時(shí)要注意下:
首先得了解下Thread.sleep()函數(shù):
public static native void sleep(long millis) throws InterruptedException
當(dāng)該線程休眠時(shí)如果中斷則會(huì)拋出該錯(cuò)誤,此異常非運(yùn)行時(shí)異常,必須捕獲且處理。
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread() {
@Override
public void run () {
while (true) {
if (Thread.currentThread().isInterrupted()){
//此方法返回中斷狀態(tài),且不會(huì)清除該中斷狀態(tài)
System.out.println("Interruted!");
break;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("Interruted When Sleep");
// 設(shè)置中斷狀態(tài)
Thread.currentThread().interrupt();
}
Thread.yield();
}
}
};
t1.start();
Thread.sleep(2000);
t1.interrupt();
}
在catch語塊中本可以進(jìn)行中斷退出,但我們沒這么做,因?yàn)檫@樣會(huì)破壞數(shù)據(jù)一致性和完整性(和直接使用shop()用異曲同工之妙)。所以我們在異常處理中必須重新設(shè)置中斷狀態(tài)(因?yàn)榇藭r(shí)拋出異常后狀態(tài)會(huì)被清除),讓該線程完成工作后再退出。
那么我們?nèi)绾握_地取消/關(guān)閉線程呢?
1. interrupt方法不一定會(huì)真正”中斷”線程,它只是一種協(xié)作機(jī)制,如果 不明白線程在做什么,不應(yīng)該貿(mào)然的調(diào)用線程的interrupt方法,以為這樣就能取消線程。
2. 對于以線程提供服務(wù)的程序模塊而言,它應(yīng)該封裝取消/關(guān)閉操作,提供單獨(dú)的取消/關(guān)閉方法給調(diào)用者,類似于InterruptReadDemo中演示的cancel方法,外部調(diào)用者應(yīng)該調(diào)用這些方法而不是直接調(diào)用interrupt。
3. Java并發(fā)庫的一些代碼就提供了單獨(dú)的取消/關(guān)閉方法,比如說,F(xiàn)uture接口提供了如下方法以取消任務(wù):boolean cancel(boolean mayInterruptIfRunning);
4. 再比如,ExecutorService提供了如下兩個(gè)關(guān)閉方法:
void shutdown();
List
5. Future和ExecutorService的API文檔對這些方法都進(jìn)行了詳細(xì)說明,這是我們應(yīng)該學(xué)習(xí)的方式。
以上就是Java多線程中斷機(jī)制,總的來說,就是采用了interrupt方法來中斷對應(yīng)的線程。多線程作為Java中的重難點(diǎn)知識(shí)點(diǎn),是我們學(xué)好Java的突破口,想要學(xué)好Java除了要付出時(shí)間和努力,還有有一個(gè)好的學(xué)習(xí)方法。本站的Java多線程教程里面能夠給出系統(tǒng)地學(xué)習(xí)多線程的方法,助你快速學(xué)好Java多線程!