2012年11月27日 星期二

[Java] 如何安全且優雅地停止Java執行緒?

 Java執行緒的使用上最常被問到的一個問題就是:「我該如何停止執行緒的執行?Thread.stop()方法已被標為棄用了,我該怎麼做?

 最簡單的方法是:透過一個boolean旗標值與Thread.interrupt()方法的搭配來完成,請見下列程式碼:

public class TestThread implements Runnable 
{
    private boolean isRunning = true;


    @Override
    public void run() 

    {
        System.out.println("Thread starts");
        while(
isRunning

        {
            try

            {
                //do something

                System.out.println("Sleeping...");
                Thread.sleep(5000);
            }

            catch(InterruptedException e) 
            {
                System.out.println("Thread was inturrupted");
            }

            catch(Exception e) {
                //handle error
                e.printStackTrace();
            }   
        }
        System.out.println("Thread ends");
    }
 
    public void stopThread() 

    {
        this.isRunning = false;
    }

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

    {
        TestThread task = new TestThread();
        Thread t = new Thread(task);
        t.start();
        System.out.println("Main thread Sleeping...");
        Thread.sleep(2000);


        //stop in this manner
        task.stopThread();
        t.interrupt();
    }
}


 在上述程式碼中,執行緒中的迴圈工作是否要持續執行是依靠TestThread中的isRunning布林值而定的;也就是說,我們只要在TestThread中加入一個將isRunning的值變為false的方法便可控制TestThread是否繼續執行

 但問題出現了,即便我們透過改變isRunning值來阻止TestThread的下次執行,但執行續依舊會完成這次迴圈的工作執行,直到下次迴圈判斷時才真的停止。因此,除了呼叫stopThread()方法改變旗標職外,我們還要呼叫該執行緒的interrupt()方法,讓該執行緒丟出InterruptedException好脫離原本的執行流程,順利進入下次迴圈判斷;透過這兩個工具,我們即可達成不透過stop()方法亦能安全停止執行緒的目的了:)

1 則留言: