jdk1.8之線程中斷

在Core Java中有這樣一句話:"沒有任何語言方面的需求要求一個被中斷的程序應該終止。中斷一個線程只是爲了引發該線程的注意,被中斷線程能夠決定如何應對中斷 "
線程中斷不會使線程當即退出,而是給線程發送一個通知,告知目標線程有人但願你退出。至於目標線程接收到通知後如何處理,則徹底由目標線程自行決定。網絡

線程中斷有關的三個方法

  • void Thread.interrupt();//中斷線程
  • boolean Thread.isInterrupted()//判斷是否中斷
  • static boolean Thread.interrupted()//判斷是否中斷,並清除當前中斷狀態
  • Thread.interrupt()方法是一個實例方法,它通知目標線程中斷,也就是設置中斷標誌位。中斷標誌位表示當前線程已經被中斷了。
  • Thread.isInterrupted()方法也是實例方法,它判斷當前線程是否有被中斷(經過檢查中斷標誌位)。

靜態方法Thread.interrupted()也是用來判斷當前線程的中斷狀態,但同時會清除當前線程的中斷標誌位狀態。ide

運行中的線程不會由於interrupt()而中斷,由於它僅僅是一個信號(status)線程

public static void main(String[] intsmaze) throws InterruptedException {
        Thread t1=new Thread()
        {
            public void run()
            {
                while(true){ }
            }
        };     
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();
    }

這個程序雖然對t1進程了中斷,可是在t1中並無中斷處理的邏輯,所以即便t1線程被置上了中斷狀態,可是這個中斷不會發生任何做用。
若是但願t1在中斷後退出,必須爲他增長相應的中斷處理代碼,以下code

public static void main(String[] intsmaze) throws InterruptedException {
        Thread t1=new Thread()
        {
            public void run()
            {
                while(true)
                {
                    if(Thread.currentThread().isInterrupted())//判斷當前線程是否中斷。
                    {
                        System.out.println("intsmaze Interrupt");
                        break;
                    }
                }
            }
        };
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();
    }

等待中的線程(wait(long),sleep(long),join(long)收到中斷信號會拋出InterruptedException

public static native void sleep(long millis) throws InterruptedException;會拋出一箇中斷異常。當線程在休眠sleep時,若是被中斷就會產生該異常,此時它會清楚中斷標誌,若是不加處理,那麼在下一次循環開始時,就沒法捕獲這個中斷。
若是註釋掉catch中的Thread.currentThread().interrupt();咱們能夠發現,程序一直運行,線程沒有中止;反之放開該註釋,則發現程序運行結束了。對象

public static void main(String[] intsmaze) throws InterruptedException {
        Thread t1=new Thread()
        {
            public void run()
            {
                while(true)
                {
                    if(Thread.currentThread().isInterrupted())
                    {
                        System.out.println("intsmaze Interrupt");
                        break;
                    }               
                    try {
                        Thread.sleep(6000);
                    } catch (InterruptedException e) {
                        System.out.println("Interrupt when intsmaze sleep");
                        Thread.currentThread().interrupt();//設置中斷狀態
                    }
                }
            }
        };
        
        t1.start();
        Thread.sleep(2000);
        t1.interrupt();
    }

BLOCKED

若是線程在等待鎖,對線程對象調用interrupt()只是會設置線程的中斷標誌位,線程依然會處於BLOCKED狀態,也就是說,interrupt()並不能使一個在等待鎖的線程真正」中斷」。經過前面的代碼能夠看到,中斷是經過循環不判進行Thread.currentThread().isInterrupted()判斷的。
在使用synchronized關鍵字獲取鎖的過程當中不響應中斷請求,這是synchronized的侷限性。若是想在等待獲取鎖的過程當中能響應中斷,應該使用顯式鎖,Lock接口,它支持以響應中斷的方式獲取鎖。接口

NEW/TERMINATE

若是線程還沒有啓動(NEW),或者已經結束(TERMINATED),則調用interrupt()對它沒有任何效果,中斷標誌位也不會被設置。好比說,如下代碼的輸出都是false。進程

IO操做

若是線程在等待IO操做,尤爲是網絡IO,則會有一些特殊的處理。
若是IO通道是可中斷的,即實現了InterruptibleChannel接口,則線程的中斷標誌位會被設置,同時,線程會收到異常ClosedByInterruptException。
若是線程阻塞於Selector調用,則線程的中斷標誌位會被設置,同時,阻塞的調用會當即返回。
咱們重點介紹另外一種狀況,InputStream的read調用,該操做是不可中斷的,若是流中沒有數據,read會阻塞 (但線程狀態依然是RUNNABLE),且不響應interrupt(),與synchronized相似,調用interrupt()只會設置線程的中斷標誌,而不會真正」中斷」它,咱們看段代碼。it

public class InterruptReadDemo {
    private static class A extends Thread {
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()){
                try {
                    System.out.println(System.in.read());
                } catch (IOException e) {
                    e.printStackTrace();
                }    
            }
            System.out.println("exit");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        A t = new A();
        t.start();
        Thread.sleep(100);
        t.interrupt();
    }
}

線程t啓動後調用System.in.read()從標準輸入讀入一個字符,不要輸入任何字符,咱們會看到,調用interrupt()不會中斷read(),線程會一直運行。io

拿兩年前的筆記出來冒個泡

相關文章
相關標籤/搜索