java|线程异常处理 重启
线程的异常处理不能像普通程序一样出现异常后抛出然后由创建并启用该线程的主线程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();
}
}
被观察者
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();
}
}
}
主线程
/**
* 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();
}
}
二、内存模式
具体原理为在内存中建立一个唯一的子线程标示,一旦子线程异常后,删除标示,子线程启动后,创建标示,然后监控线程时刻监视标示,一旦标示不存在了,就启动一个新的子线程,以此来实现线程异常后的重启。
内存线程类
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;
}
}
}
子线程
class childThread implements Runnable{public void run(){
try{
//do something
}
catch(Exception outEx){
//log
}
finally{
//删除childThread标示
Thread thread = ThreadUtil.getLocalThread();
ThreadUtil.deleteThread(thread);
}
}
}
【java|线程异常处理 重启】监控线程
/**
* 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();
}
}
}
}
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 事件代理
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- Linux下面如何查看tomcat已经使用多少线程
- 数组常用方法一
- 【Hadoop踩雷】Mac下安装Hadoop3以及Java版本问题
- Java|Java基础——数组
- 多线程NSOperation
- RxJava|RxJava 在Android项目中的使用(一)