Java线程意外退出线程后自动重启
创始人
2025-05-31 18:34:34

最近有个简单需求,创建了一个线程用来循环读取队列中的数据,然后存到数据库,一切美好都源自于想象。殊不知线程总是莫名其妙的死亡。所以决定用观察者模式去监听线程;

前置知识

Observable与Observer

  • 在Java中通过Observable类和Observer接口实现了观察者模式。一个Observer对象监视着一个Observable对象的变化,当Observable对象发生变化时,Observer得到通知,就可以进行相应的工作。例如在文档/视图结构中,文档被修改了,视图就会得到通知。

  • java.util.Observable中有两个方法对Observer特别重要,一个是setChange()方法用来设置一个内部标志位注明数据发生了变化;一个是notifyObservers()方法会去调用一个列表中所有的Observer的update()方法,通知它们数据发生了变化。

  • Observer通过Observable的addObserver()方法把自己添加到这个列表中。这个列表虽然由Observable拥有,但Observable并不知道到底有哪些Observer正在观察等待通知。Observable只提供一个方法让Observer能把自己添加进列表,并保证会去通知Observer发生了变化。通过这种机制,可以有任意多个Observer对Observable进行观察,而不影响Observable的实现。

被监听的类

import cn.hutool.core.date.DateUtil;
import java.util.Observable;public  class RunThread1 extends Observable implements Runnable{private String name;public RunThread1(String name){this.name=name;}// 此方法一经调用,立马可以通知观察者,在本例中是监听线程public void doBusiness(){if ( true ){super .setChanged();}notifyObservers();}@Overridepublic void run() {int c =  0 ;while ( true ){     //模拟线程运行一段时间之后退出System.out.println( "Runing- " +c+ " "+name + DateUtil.now());try {Thread.sleep( 2000 );} catch  (InterruptedException e) {e.printStackTrace();doBusiness();break ;}c++;//模拟抛出异常try {if (c==  4 ){String str =  null ;str.length(); //此处将会抛出空指针异常}} catch  (Exception e) {e.printStackTrace();doBusiness(); //在抛出异常时调用,通知观察者,让其重启线程break ; //异常抛出之后,一定要跳出循环,保证将线程送进地狱}}    }
} 

观察者类

import  java.util.Observable;
import  java.util.Observer;
public  class Listener1 implements  Observer{private String name;public Listener1(String name){this.name=name;};@Overridepublic void update(Observable o, Object arg) {System.out.println( "RunThread死机" );RunThread1 run =  new RunThread1(name);run.addObserver( this );new Thread(run).start();System.out.println( "RunThread重启" );}
}

开始测试

测试代码

     public static  void  main(String[] args) {String name="lasse";RunThread1 run =  new RunThread1(name);Listener1 listen =  new Listener1(name);run.addObserver(listen);new Thread(run).start();//run.doBusiness();}

测试结果

Runing- 0 lasse2023-03-21 11:32:08
Runing- 1 lasse2023-03-21 11:32:10
Runing- 2 lasse2023-03-21 11:32:12
Runing- 3 lasse2023-03-21 11:32:14
java.lang.NullPointerException
at com.bcy.adaptor.starter.RunThread1.run(RunThread1.java:36)
at java.lang.Thread.run(Thread.java:748)
RunThread死机
RunThread重启
Runing- 0 lasse2023-03-21 11:32:16
Runing- 1 lasse2023-03-21 11:32:18
Runing- 2 lasse2023-03-21 11:32:20
Runing- 3 lasse2023-03-21 11:32:22
java.lang.NullPointerException
at com.bcy.adaptor.starter.RunThread1.run(RunThread1.java:36)
at java.lang.Thread.run(Thread.java:748)
RunThread死机
RunThread重启
Runing- 0 lasse2023-03-21 11:32:24
Runing- 1 lasse2023-03-21 11:32:26
Runing- 2 lasse2023-03-21 11:32:28
Runing- 3 lasse2023-03-21 11:32:30
java.lang.NullPointerException
at com.bcy.adaptor.starter.RunThread1.run(RunThread1.java:36)
at java.lang.Thread.run(Thread.java:748)
RunThread死机
RunThread重启
。。。。。。

相关内容

热门资讯

cad打印线条粗细设置 cad... 004-线型(下)打印样式设置和线型文件使用一、线宽设置方法制图规范里边的线宽要求,我们已经定义好,...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...