天天看點

如何停止JAVA線程

如何停止java的線程一直是一個困惱我們開發多線程程式的一個問題。這個問題最終在java5的java.util.concurrent中得到了回答:使用interrupt(),讓線程在run方法中停止。

在java的多線程程式設計中,java.lang.thread類型包含了一些列的方法start(), stop(), stop(throwable) and suspend(), destroy() and resume()。通過這些方法,我們可以對線程進行友善的操作,但是這些方法中,隻有start()方法得到了保留。

在sun公司的一篇文章《why are thread.stop, thread.suspend and thread.resume

deprecated? 》中詳細講解了舍棄這些方法的原因。那麼,我們究竟應該如何停止線程呢?

在《why are thread.stop, thread.suspend and thread.resume deprecated? 》中,建議使用如下的方法來停止線程:

    private volatile thread blinker; 

    public void stop() { 

        blinker = null; 

    } 

    public void run() { 

        thread thisthread = thread.currentthread(); 

        while (blinker == thisthread) { 

            try { 

                thisthread.sleep(interval); 

            } catch (interruptedexception e){ 

            } 

            repaint(); 

        } 

    }

關于使用volatile關鍵字的原因,請檢視http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#36930。

當線程處于下面的狀況時,屬于非運作狀态:

當sleep方法被調用。

當wait方法被調用。

當被i/o阻塞,可能是檔案或者網絡等等。

當線程處于上述的狀态時,使用前面介紹的方法就不可用了。這個時候,我們可以使用interrupt()來打破阻塞的情況,如:

當interrupt()被調用的時候,interruptedexception将被抛出,是以你可以再run方法中捕獲這個異常,讓線程安全退出:

當線程被i/o阻塞的時候,調用interrupt()的情況是依賴與實際運作的平台的。在solaris和linux平台上将會抛出interruptedioexception的異常,但是windows上面不會有這種異常。是以,我們處理這種問題不能依靠于平台的實作。如:

另外,我們也可以使用interruptiblechannel接口。 實作了interruptiblechannel接口的類可以在阻塞的時候抛出<code>closedbyinterruptexception</code>。如:

這裡還需要注意一點,當線程處于寫檔案的狀态時,調用interrupt()不會中斷線程。

how to stop a thread or a task

why are thread.stop, thread.suspend and thread.resume deprecated?

java threads, third edition o'reilly