keep moving!

We must not cease from exploration. And the end of all our exploring will be to arrive where we began and to know the place for the first time.
随笔 - 37, 文章 - 2, 评论 - 3, 引用 - 0
数据加载中……

Design Pattern: Two-phase Termination 模式

Two-phase Termination直譯的話是「兩相終止」,不過就這個模式而言,該譯作「兩階段終止」比較適當,想像您有一個執行緒正在週期性的運作,在「運作階段」您送出了停止執行緒的請求,這時候執行緒不該慌張的馬上終止目前的工作,而是先完成這一次週期的工作,然後進入「善後階段」完成一些善後的工作,例如關閉檔案或網路串流,所謂的兩階段終止,即中止「運作階段」,並完成「善後階段」,完整的完成執行緒的工作。

以Java的Thread終止而言,不建議您直接使用stop()方法來終止執行緒,stop()方法會丟出ThreadDeath例外強迫執行緒終止,即使執行緒正在運作階段或執行至synchronized區,如果您要終止執行緒,建議自行實作,例如:
  public class SomeThread extends Thread {
    private boolean isTerminated = false;

    public void terminate() {
        isTerminated = true;
    }

    public void run() {
        while(!isTerminated) {
            // ... some statements
        }
    }
 }
 
考慮到有時執行緒可能會執行至sleep()或wait()而進入Not Runnable狀態,使用上面的方法可能會延遲終止的請求,因而可以在要求終止時再呼叫interrupt()方法,這會丟出 InterruptedException,而使得執行緒從Not Runnable狀態中離開,因此可以改變一下程式:
 public class SomeThread extends Thread {
    private boolean isTerminated = false;

    public void terminate() {
        isTerminated = true;
        interrupt();
    }

    public void run() {
        try {
            while(!isTerminated) {
                // ... some statements
            }
        }
        catch(InterruptedException e) {
        }
    }
 }
 
在發出中止請求之後,如果執行緒是在Not Runnable狀態,會丟出InterruptedException,如果這個例外沒有先被捕捉,就會被run()中的catch InterruptedException捕捉,也就是說會直接離開while迴圈,因而如果您在發出終止請求後,要求先執行完這一個週期的工作,您要先捕捉這個例外,若不用完成這一個週期的工作,則不用捕捉這個例外,要如何作取決於您的程式。

如果執行緒要完成這一個週期的工作,在下一個週期開始之前檢查旗標,這時它的結果是false,所以離開while迴圈,這時候您可以進行一些善後工作,這個可以寫在finally區塊中,例如:
 public class SomeThread extends Thread {
    private boolean isContinue = false;

    public void terminate() {
        isTerminated = true;
        interrupt();
    }

    private void doWorkBeforeShutdown() {
        // .... do some work before shutdown
    }

    public void run() {
        try {
            while(!_isTerminated) {
                // ... some statements
            }
        }
        catch(InterruptedException e) {
        }
        finally {
            doWorkBeforeShutdown();
        }
    }
 }
 
上面這個程式大致上就是Two-phase Termination模式的架構,另外如果您的執行緒還服務著其它的物件,則在送出終止請求到完全終止之前,應該停止服務其它物件,您可以讓其它物件要求服務之前,先查詢執行緒是否已被要求終止,這可以藉由提供一個方法來達到:
 public class SomeThread extends Thread {
    private boolean isTerminated = false;

    public void terminate() {
        isTerminated = true;
        interrupt();
    }

    public boolean isTerminated() {
        return _isTerminated;
    }

    private void doWorkBeforeShutdown() {
        // .... do some work before shutdown
    }

    public void run() {
        try {
            while(!_isTerminated) {
                // ... some statements
            }
        }
        catch(InterruptedException e) {
        }
        finally {
            doWorkBeforeShutdown();
        }
    }
 }


张金鹏 2007-04-17 10:58 发表评论

文章来源:http://www.blogjava.net/jesson2005/articles/111202.html

posted on 2008-09-07 11:06 大石头 阅读(121) 评论(0)  编辑  收藏 所属分类: 多线程


只有注册用户登录后才能发表评论。


网站导航: