[Java] 執行緒的停止

Posted in :

結論是,thread run 完 run() { } 就結束了,所以讓 run() 裡執行無窮迴圈就永遠不會結束。


Once a thread stops you cannot restart it. However, there is nothing stopping you from creating and starting a new thread.

Option 1: Create a new thread rather than trying to restart.

Option 2: Instead of letting the thread stop, have it wait and then when it receives notification you can allow it to do work again. This way the thread never stops and will never need to be restarted.

Edit based on comment:

To “kill” the thread you can do something like the following.

yourThread.setIsTerminating(true); // tell the thread to stop
yourThread.join(); // wait for the thread to stop

如果您想要停止一個執行緒的執行,當您查看API時,您會發現Thread的stop()方法已經被標示為 “deprecated”,使用這個方法來停止一個執行緒是不被建議的。

請見:Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?

如果您想要停止一個執行緒,您最好自行實作。

一個執行緒要進入Dead狀態,就是執行完run()方法,簡單的說,如果您想要停止一個執行緒的執行,就要提供一個方式讓執行緒可以執行完run(),而這也是您自行實作執行緒停止的基本概念。

例如,如果執行緒的run()方法中執行的是一個重複執行的迴圈,您可以提供一個flag來控制迴圈是否執行,藉此讓迴圈有可能終止、執行緒可以離開 run()方法以終止執行緒:

public class SomeThread implements Runnable {
private boolean isContinue = true;

public void terminate() {
isContinue = false;
}

public void run() {
while(isContinue) {
// … some statements
}
}
}


如果執行緒因為執行sleep()或是wait()而進入Not Runnable狀態,而您想要停止它,您可以使用interrupt(),而程式會丟出InterruptedException例外,因而使得執行緒 離開run()方法,例如:

  • SomeThread.java
package onlyfun.caterpillar;

public class SomeThread implements Runnable {
    public void run() { 
        System.out.println("sleep....going to not runnable"); 
        try { 
            Thread.sleep(9999); 
        } 
        catch(InterruptedException e) { 
            System.out.println("I am interrupted...."); 
        } 
    } 
}

 

  • Main.java
package onlyfun.caterpillar;

public class Main { 
    public static void main(String[] args) { 
        Thread thread = new Thread(new SomeThread()); 
        thread.start(); 
        thread.interrupt(); 
    } 
}

如果程式因為I/O而停滯,進入Not Runnable狀態,基本上您必須等待I/O完成才能離開Not Runnable,您無法使用interrupt()來使得執行緒離開run()方法,您要提供替代的方法,基本上的概念也是引發一個例外,而這個例外要 如何引發,要看您所使用的I/O而定,例如您使用readLine()在等待網路上的一個訊息,此時執行緒進入Not Runnable直到讀到一個訊息,您要讓它離開run()的方法就是使用close()關閉它的串流,這時會引發一個IOException例外而使得 執行緒離開run()方法,例如:

public class Client implements Runnable {
private Socket skt;
// …..

public void terminate() {
skt.close();
}

public void run() {
// …..

try {
BufferedReader buf = new BufferedReader(
new InputStreamReader(skt.getInputStream()));

// 讀取客戶端訊息
// 執行readLine()會進入Not runnable狀態
// 直到讀到客戶端訊息
while((userMessage = buf.readLine()) != null) {
// ….
}
}
catch(IOException e) {
System.out.println(“執行緒被終止…….”);
}
}
}


上面這個程式是個簡單的架構示範,實際的設計必須視您的程式功能與I/O類型而定。

除了stop()之外,suspend()、resume()方法也被標示為”deprecated”,這些方法如果您要達成相同的功能,您都必須自行實作,在將來新的Java版本中如果這些功能被實現,它也可能是新的介面,而不是使用現有的方法。

有關於執行緒的終止,還可以參考 Two-phase Termination 模式

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *