http://www.35java.com/zhibo/forum.php?mod=viewthread&tid=296&extra=page%3D1
Two-phaseTermination直译的话是“两相终止”,不过就这个模式而言,该译作“两阶段终止”比较适当,想像您有一个执行绪正在周期性的运作,在“运作阶段”您送出了停止执行绪的请求,这时候执行绪不该慌张的马上终止目前的工作,而是先完成这一次周期的工作,然后进入“善后阶段”完成一些善后的工作,例如关闭档案或网路串流,所谓的两阶段终止,即中止“运作阶段”,并完成“善后阶段”,完整的完成执行绪的工作。 以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()而进入NotRunnable状态,使用上面的方法可能会延迟终止的请求,因而可以在要求终止时再呼叫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) { } } } 在发出中止请求之后,如果执行绪是在NotRunnable状态,会丢出InterruptedException,如果这个例外没有先被捕捉,就会被run()中的catchInterruptedException捕捉,也就是说会直接离开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-phaseTermination模式的架构,另外如果您的执行绪还服务着其它的物件,则在送出终止请求到完全终止之前,应该停止服务其它物件,您可以让其它物件要求服务之前,先查询执行绪是否已被要求终止,这可以藉由提供一个方法来达到: 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(); } } } |