|
|
如果你想要停止一個執行緒的執行,當你查看API時,你會發現Thread的stop()方法已經被標示為deprecated,使用這個方法來停止一個執行緒是不被建議的。 請見:Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated? 如果你想要停止一個執行緒,你最好自行實作。 一個執行緒要進入死亡(Dead)狀態,就是執行完run()方法,簡單的說,如果你想要停止一個執行緒的執行,就要提供一個方式讓執行緒可以執行完run(),而這也是自行實作執行緒停止的基本概念。 例如,如果執行緒的run()方法中執行的是一個重複執行的迴圈,你可以提供一個控制旗標(Flag)來控制迴圈是否執行,藉此讓迴圈有可能終止、執行緒可以離開 run()方法以終止執行緒: public class Some implements Runnable {
private boolean isContinue = true; public void terminate() { isContinue = false; } public void run() { while(isContinue) { // ... some statements } } } 如果執行緒因為執行sleep()或是wait()而進入阻斷(Blocked)或等待池(Wait)狀態,而你想要停止它,你可以使用interrupt(),而程式會丟出InterruptedException例外,因而使得執行緒 離開run()方法。例如:
public class Some implements Runnable {
public class Main {
如果程式因為IO而進入阻斷狀態,基本上你必須等待IO完成才能離開阻斷狀態,你無法使用interrupt()來使得執行緒離開run()方法,你要提供替代的方法,基本上的概念也是引發一個例外,而這個例外要 如何引發,要看你所使用的IO而定。 例如你使用readLine()在等待網路上的一個訊息,此時執行緒進入阻斷狀態直到讀到訊息,你要讓它離開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()會進入阻斷狀態 // 直到讀到客戶端訊息 while((userMessage = buf.readLine()) != null) { // .... } } catch(IOException e) { System.out.println("執行緒被終止......."); } } } 上面這個程式是個簡單的架構示範,實際的設計必須視你的程式功能與IO類型而定。 除了stop()之外,suspend()、resume()方法也被標示為"deprecated",這些方法如果你要達成相同的功能,你都必須自行實作,在將來新的Java版本中如果這些功能被實現,它也可能是新的介面,而不是使用現有的方法。 有關於執行緒的終止,還可以參考 Two-phase Termination 模式。 |