Java線程停止方法之Interrupt方法

來源:互聯網
上載者:User

Java線程停止方法之Interrupt方法

最近在學習Java多線程相關的知識點,其中關於線程停止的方法網上也有不少大牛給出了詳細的解答,而我這邊就其中Interrupt方法的注意點給自己提個醒。

  首先還是大概的羅列下停止線程的方法:

  1、使用stop()方法等,不過已經不再被推薦使用,和suspend、resume一樣。

  2、使用退出標誌終止線程,引入一個共用變數,volatile類型或者使用synchronized來監視共用變數相關操作的方法,然後在run()方法中,通過while迴圈不停的輪詢這個標誌。

  3、使用Interrupt方法中斷線程。

  注意點:我一開始看到該方法的時候,認為interrupt會使線程停止運行,但事實上並非如此,調用一個線程的Interrupt方法會把線程的狀態改為中斷態。這其中又可以細分成兩個方面:

  1)對於因執行了sleep、wait、join方法而休眠的線程:調用Interrupt方法會使他們不再休眠,同時會拋出 InterruptedException異常。比如一個線程A正在sleep中,這時候另外一個程式裡去調用A的interrupt方法,這時就會迫使A停止休眠而拋出InterruptedException異常,從而提前使線程逃離阻塞狀態。

  2)對於正在啟動並執行線程,即沒有阻塞的線程,調用Interrupt方法就只是把線程A的狀態改為interruptted,但是不會影響線程A的繼續執行。

以下是對處於阻塞狀態線程使用Interrupt方法的例子:

class MyThread extends Thread { 
    volatile boolean stop = false; 
    public static void main( String args[] ) throws Exception { 
        MyThread thread = new MyThread(); 
        System.out.println( "Starting thread..." ); 
        thread.start(); 
        Thread.sleep( 3000 ); 
        System.out.println( "hread stop..." ); 
        thread.stop = true;  //如果線程阻塞,將不會檢查此變數 
        thread.interrupt(); 
        Thread.sleep( 3000 ); 
        System.out.println( "end..." ); 
    } 
 
    public void run() { 
        while ( !stop ) { 
            System.out.println( "Thread running..." ); 
            try { 
                Thread.sleep( 1000 ); 
            } catch ( InterruptedException e ) { 
                System.out.println( "Thread interrupted..." ); 
            } 
        } 
        System.out.println( "Thread exiting under request..." ); 
    } 
}

說明:對於被上述幾種方法阻塞的線程,正確的停止線程方式是設定共用變數,並調用interrupt()(注意變數應該先設定)。設定共用變數是為了沒有被阻塞的線程也能正常退出。

  以下內容還在繼續研究中

  在看一些博主的文章時還看到了一些特殊情況,也在這邊做個補充:

  線程在I/O操作進行時被阻塞

 

  分兩種情況:

  1)使用通道(channels)的情況,通道是Java 1.4引入的I/O API,被阻塞的線程將收到一個ClosedByInterruptException異常。這與使用Interrupt方法拋出異常的用法一樣,只是異常不同而已。

  2)使用傳統的I/O。

  說明:即使Interrupt方法被調用了,Thread.interrupt()也不起作用,因為線程將不會退出被阻塞狀態。

  解決辦法:調用阻塞該線程的通訊端的close()方法。在這種情形下,如果線程被I/O操作阻塞,該線程將接收到一個SocketException異常,這與使用interrupt()方法引起一個InterruptedException異常被拋出非常相似。  注意:唯一要說明的是,必須存在socket的引用(reference),只有這樣close()方法才能被調用。這意味著socket對象必須被共用。  以下代碼供參考:

class MyThread extends Thread { 
    volatile boolean stop = false; 
    volatile ServerSocket socket; 

    public static void main( String args[] ) throws Exception { 
        MyThread thread = new MyThread(); 
        System.out.println( "Starting thread..." ); 
        thread.start(); 
        Thread.sleep( 3000 ); 
        System.out.println( "Asking thread to stop..." ); 
        thread.stop = true; 
        thread.socket.close(); 
        Thread.sleep( 3000 ); 
        System.out.println( "Stopping application..." );   
    }
 
    public void run() { 
        try { 
            socket = new ServerSocket(7856); 
        } catch ( IOException e ) { 
            System.out.println( "Could not create the socket..." ); 
            return; 
        } 
        while ( !stop ) { 
            System.out.println( "Waiting for connection..." ); 
            try { 
                Socket sock = socket.accept(); 
            } catch ( IOException e ) { 
                System.out.println( "accept() failed or interrupted..." ); 
            } 
        } 
        System.out.println( "Thread exiting under request..." ); 
    } 
}

以上是自己對停止線程方法的一些總結,當然也是借鑒了不少博主的分享。重點放在了Interrupt方法,因為這邊容易理解出錯!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.