最近在開發blog的註冊系統的時候遇到一個小小的困難,因為blog的註冊是通過訪問blog系統的頁面並類比人的行為來為使用者註冊的,在正常情況下是
沒有問題的,但是如果遇到異常,這樣的註冊方式就顯得很脆弱了,比如使用者已經註冊過,這個時候雖然頁面上會出現錯誤提示,但是用程式來捕捉這樣的提示比較
困難,而且如果這樣做還需要加上更多的判斷,考慮各種可能的異常情況,如果考慮不全,會極大降低該模組的可靠度。考慮再三之後,索性我就不去考慮有哪些異
常情況了,全部統一處理,規定在一定時間內,這個註冊blog的行為不能完成就認為是註冊失敗。
處理方案是有了,那該怎麼實現這樣的功能呢?在網上查閱了許多資料之後,找到了有個叫做守護線程的東西,覺得用它來完成這樣的需求倒是挺方便的,所以在這裡分享給大家。
首先,守護線程類如下:
/**
* 本線程設定了一個逾時時間
* 該線程開始運行後,經過指定逾時時間,
* 該線程會拋出一個未檢查異常通知調用該線程的程式逾時
* 在逾時結束前可以調用該類的cancel方法取消計時
*/
public class TimeoutThread extends Thread{
/**
* 計時器逾時時間
*/
private long timeout;
/**
* 計時是否被取消
*/
private boolean isCanceled = false;
/**
* 當計時器逾時時拋出的異常
*/
private TimeoutException timeoutException;
/**
* 構造器
*
* @param timeout
* 指定逾時的時間
*/
public TimeoutThread(long timeout, TimeoutException timeoutErr) {
super();
this.timeout = timeout;
this.timeoutException = timeoutErr;
// 設定本線程為守護線程
this.setDaemon(true);
}
/**
* 取消計時
*/
public synchronized void cancel() {
isCanceled = true;
}
/**
* 啟動逾時計時器
*/
public void run() {
try {
Thread.sleep(timeout);
if (!isCanceled)
throw timeoutException;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
下面定義要在TimeoutThread中拋出的異常,這個異常是關鍵,因為我們完全依靠捕捉這個異常才能知道我們需要執行的任務是否逾時了,而且
這個異常還有一個特殊之處在於,它不繼承自Exception,而是繼承自RuntimeException,這是為什麼呢?原因是run方法重寫了
Thread中的run()方法,該方法不能拋出已檢測的異常:
public class TimeoutException extends RuntimeException {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 5961292480921511543L;
public TimeoutException(String errMessage){
super(errMessage);
}
}
現在萬事具備,工具已經做好了,就差在需要的地方使用了,這種方式使用起來也是特別簡潔明了,使用方法如下:
TimeoutThread t = new TimeoutThread(5000,new TimeoutException(”逾時”));
try{
t.start();
//需要計時的任務
webAction();
t.cancel();
}catch(TimeoutException e){
//對逾時的處理
throw new AreadyRegedException(”使用者可能已經註冊了blog,或訪問blog系統時發生異常,請檢查!”);
}