執行緒異常重啟
阿新 • • 發佈:2019-01-07
執行緒的異常處理不能像普通程式一樣出現異常後丟擲然後由建立並啟用該執行緒的主執行緒try catch後進行異常處理,而是隻能由該子執行緒自己try catch自己的異常,比如該子執行緒中連線資料庫或者操作檔案,會有可能出現IOException或者SQLException等異常,而且這些異常一旦發生,執行緒就會中止,中止的執行緒並不會對其他執行緒或者主執行緒造成影響,不過有時當我們用子執行緒去連線資料庫時,假如連線不上,會丟擲異常,而我們希望自動斷線間隔重連,即子執行緒出現異常停止後,通知主執行緒在適當的時間後再次重啟子執行緒,此時可以使用兩種方法(有可能還有方法,只是目前我所知道的有兩種),第一種使用java1.5以上自帶的Observable和Observer,即觀察者模式,第二種是使用原始記憶體模式(第一種有可能是封裝好的也是基於記憶體實現,沒去看原始碼)。
一、觀察者模式
1.介紹
在Java中通過Observable類和Observer介面實現了觀察者模式。一個Observer物件監視著一個Observable物件的變化,當Observable物件發生變化時,Observer得到通知,就可以進行相應的工作。
2.實現方法
觀察者:
/**
* Created by Administrator on 2016-03-24.
*
* 觀察者 執行緒 類
*
*/
class SimpleObserver implements Observer {
@Override
public void update(Observable observable ,Object data){
//重啟執行緒
System.out.println("5秒後重啟執行緒");
Thread.sleep(5000);
SimpleObservable simpleObservable = new SimpleObservable();
SimpleObserver simpleObserver = new SimpleObserver();
//需要將觀察者類加入到被觀察者的觀察者列表中
simpleObservable.addObserver(simpleObserver);
simpleObservable.run();
}
}
- 1
被觀察者
import java.sql.SQLException
/**
* Created by Administrator on 2016-03-24.
*
* 被觀察者 執行緒 類
*/
class SimpleObservable extends Observable implements Runnable{
public void run(){
try {
//System.out.println("下面進行JDBC連線");
/**
* Do jdbc
*/
//測試
int a = 100 / 0 ;
} catch (SQLException e) {
//處理連線異常,自動重啟該執行緒
setChanged();
//只有在setChange()被呼叫後,notifyObservers()才會去呼叫update(),否則什麼都不幹。
notifyObservers();
} catch (Exception et){
System.out.println("出現異常");
setChanged();
notifyObservers();
}
}
}
- 1
- 2
- 3
主執行緒
/**
* Created by Administrator on 2016-03-24.
*/
class MainThread {
public static void main(String[] args) {
//建立觀察者物件
SimpleObserver simpleObserver = new SimpleObserver();
//建立被觀察者物件
SimpleObservable simpleObservable = new SimpleObservable();
//需要將觀察者類加入到被觀察者的觀察者列表中
simpleObservable.addObserver(simpleObserver);
//啟動被觀察者,觀察者執行緒也會同時被啟動
simpleObservable.run();
}
}
- 1
- 2
二、記憶體模式
具體原理為在記憶體中建立一個唯一的子執行緒標示,一旦子執行緒異常後,刪除標示,子執行緒啟動後,建立標示,然後監控執行緒時刻監視標示,一旦標示不存在了,就啟動一個新的子執行緒,以此來實現執行緒異常後的重啟。
記憶體執行緒類
public class ThreadUtil
{
private static Thread thread;
private ThreadUtil( ) {
}
//新增執行緒標示
public static addThread(Thread value){
if(thread == null){
thread = value;
}
}
//獲取執行緒標示
public static Thread getLocalThread(){
if(thread){
return thread;
}
else return null;
}
//刪除執行緒標示
public static deleteThread(Thread value){
if(thread != null){
thread = null;
}
}
}
- 1
- 2
- 3
子執行緒
class childThread implements Runnable{
public void run(){
try{
//do something
}
catch(Exception outEx){
//log
}
finally{
//刪除childThread標示
Thread thread = ThreadUtil.getLocalThread();
ThreadUtil.deleteThread(thread);
}
}
}
- 1
- 2
監控執行緒
/**
* Created by Administrator on 2016年3月23日16:36:06
*
* 監控執行緒 的 執行緒
*/
class MonitorThread implements Runnable{
public void run() {
while(true){
Thread.sleep(10000);
Thread thread = ThreadUtil.getLocalThread();
//存線上程,休眠10秒
if(thread){
LogUtil.logInfo("歷史資料上傳執行緒正常執行");
}
//不存線上程,重啟執行緒
else{
Thread newThread = new Thread(new childThread());
ThreadUtil.addThread(newThread);;
thread.start();
}
}
}
}
轉載自:http://blog.csdn.net/liuyuqin1991/article/details/50971585