Design Pattern: Two-phase Termination 模式
Two-phase Termination直譯的話是「兩相終止」,不過(guò)就這個(gè)模式而言,該譯作「兩階段終止」比較適當(dāng),想像您有一個(gè)執(zhí)行緒正在週期性的運(yùn)作,在「運(yùn)作階段」您送出了停止執(zhí)行緒的請(qǐng)求,這時(shí)候執(zhí)行緒不該慌張的馬上終止目前的工作,而是先完成這一次週期的工作,然後進(jìn)入「善後階段」完成一些善後的工作,例如關(guān)閉檔案或網(wǎng)路串流,所謂的兩階段終止,即中止「運(yùn)作階段」,並完成「善後階段」,完整的完成執(zhí)行緒的工作。
以Java的Thread終止而言,不建議您直接使用stop()方法來(lái)終止執(zhí)行緒,stop()方法會(huì)丟出ThreadDeath例外強(qiáng)迫執(zhí)行緒終止,即使執(zhí)行緒正在運(yùn)作階段或執(zhí)行至synchronized區(qū),如果您要終止執(zhí)行緒,建議自行實(shí)作,例如:
考慮到有時(shí)執(zhí)行緒可能會(huì)執(zhí)行至sleep()或wait()而進(jìn)入Not Runnable狀態(tài),使用上面的方法可能會(huì)延遲終止的請(qǐng)求,因而可以在要求終止時(shí)再呼叫interrupt()方法,這會(huì)丟出 InterruptedException,而使得執(zhí)行緒從Not Runnable狀態(tài)中離開(kāi),因此可以改變一下程式:
在發(fā)出中止請(qǐng)求之後,如果執(zhí)行緒是在Not Runnable狀態(tài),會(huì)丟出InterruptedException,如果這個(gè)例外沒(méi)有先被捕捉,就會(huì)被run()中的catch InterruptedException捕捉,也就是說(shuō)會(huì)直接離開(kāi)while迴圈,因而如果您在發(fā)出終止請(qǐng)求後,要求先執(zhí)行完這一個(gè)週期的工作,您要先捕捉這個(gè)例外,若不用完成這一個(gè)週期的工作,則不用捕捉這個(gè)例外,要如何作取決於您的程式。
如果執(zhí)行緒要完成這一個(gè)週期的工作,在下一個(gè)週期開(kāi)始之前檢查旗標(biāo),這時(shí)它的結(jié)果是false,所以離開(kāi)while迴圈,這時(shí)候您可以進(jìn)行一些善後工作,這個(gè)可以寫(xiě)在finally區(qū)塊中,例如:
上面這個(gè)程式大致上就是Two-phase Termination模式的架構(gòu),另外如果您的執(zhí)行緒還服務(wù)著其它的物件,則在送出終止請(qǐng)求到完全終止之前,應(yīng)該停止服務(wù)其它物件,您可以讓其它物件要求服務(wù)之前,先查詢執(zhí)行緒是否已被要求終止,這可以藉由提供一個(gè)方法來(lái)達(dá)到:

文章來(lái)源:http://www.aygfsteel.com/jesson2005/articles/111202.html
以Java的Thread終止而言,不建議您直接使用stop()方法來(lái)終止執(zhí)行緒,stop()方法會(huì)丟出ThreadDeath例外強(qiáng)迫執(zhí)行緒終止,即使執(zhí)行緒正在運(yùn)作階段或執(zhí)行至synchronized區(qū),如果您要終止執(zhí)行緒,建議自行實(shí)作,例如:
public class SomeThread extends Thread {
private boolean isTerminated = false;
public void terminate() {
isTerminated = true;
}
public void run() {
while(!isTerminated) {
// ... some statements
}
}
}
private boolean isTerminated = false;
public void terminate() {
isTerminated = true;
}
public void run() {
while(!isTerminated) {
// ... some statements
}
}
}
考慮到有時(shí)執(zhí)行緒可能會(huì)執(zhí)行至sleep()或wait()而進(jìn)入Not Runnable狀態(tài),使用上面的方法可能會(huì)延遲終止的請(qǐng)求,因而可以在要求終止時(shí)再呼叫interrupt()方法,這會(huì)丟出 InterruptedException,而使得執(zhí)行緒從Not Runnable狀態(tài)中離開(kāi),因此可以改變一下程式:
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) {
}
}
}
private boolean isTerminated = false;
public void terminate() {
isTerminated = true;
interrupt();
}
public void run() {
try {
while(!isTerminated) {
// ... some statements
}
}
catch(InterruptedException e) {
}
}
}
在發(fā)出中止請(qǐng)求之後,如果執(zhí)行緒是在Not Runnable狀態(tài),會(huì)丟出InterruptedException,如果這個(gè)例外沒(méi)有先被捕捉,就會(huì)被run()中的catch InterruptedException捕捉,也就是說(shuō)會(huì)直接離開(kāi)while迴圈,因而如果您在發(fā)出終止請(qǐng)求後,要求先執(zhí)行完這一個(gè)週期的工作,您要先捕捉這個(gè)例外,若不用完成這一個(gè)週期的工作,則不用捕捉這個(gè)例外,要如何作取決於您的程式。
如果執(zhí)行緒要完成這一個(gè)週期的工作,在下一個(gè)週期開(kāi)始之前檢查旗標(biāo),這時(shí)它的結(jié)果是false,所以離開(kāi)while迴圈,這時(shí)候您可以進(jìn)行一些善後工作,這個(gè)可以寫(xiě)在finally區(qū)塊中,例如:
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();
}
}
}
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();
}
}
}
上面這個(gè)程式大致上就是Two-phase Termination模式的架構(gòu),另外如果您的執(zhí)行緒還服務(wù)著其它的物件,則在送出終止請(qǐng)求到完全終止之前,應(yīng)該停止服務(wù)其它物件,您可以讓其它物件要求服務(wù)之前,先查詢執(zhí)行緒是否已被要求終止,這可以藉由提供一個(gè)方法來(lái)達(dá)到:
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();
}
}
}
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 發(fā)表評(píng)論
文章來(lái)源:http://www.aygfsteel.com/jesson2005/articles/111202.html
posted on 2008-09-07 11:06 大石頭 閱讀(133) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): 多線程