java-重启异常断掉的线程和监控线程状态
背景
有一个线程,可能会因为异常而终止掉。为了监控这个线程,我又启动一个线程去监控。
主要代码
代码主要是由两个线程和两个可以产生异常的方法,内容跟简单,如下
import java.time.LocalDateTime;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class threadd {
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
int i = 0;
while (true) {
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if (i == 10) {
writeSth1();
}
System.out.println(LocalDateTime.now()+" "+i);
}
}
};
final Thread[] thread = {new Thread(runnable,"main thread")};
thread[0].start();
new Thread(new Runnable() {
@Override
public void run () {
while (true) {
try {
Thread.sleep(1000);
System.out.println(thread[0].getState());
if (!thread[0].isAlive()) {
System.out.println(LocalDateTime.now()+" 5秒后重启");
Thread.sleep(5000);
thread[0] = new Thread(runnable);
thread[0].start();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"check thread").start();
}
public static void writeSth1 () {
writeSth();
}
public static void writeSth() {
System.out.println(9 / 0);
}
}
打印结果
从下面结果看,等i等于10的时候程序就会执行writeSth1 而产生异常,此时线程状态是TERMINATED,接着重启又继续跑10次,符合预期
RUNNABLE
2024-09-25T13:49:59.347 1
TIMED_WAITING
2024-09-25T13:50:00.354 2
TIMED_WAITING
2024-09-25T13:50:01.360 3
TIMED_WAITING
2024-09-25T13:50:02.366 4
TIMED_WAITING
2024-09-25T13:50:03.370 5
TIMED_WAITING
2024-09-25T13:50:04.374 6
TIMED_WAITING
2024-09-25T13:50:05.377 7
TIMED_WAITING
2024-09-25T13:50:06.380 8
TIMED_WAITING
2024-09-25T13:50:07.384 9
TIMED_WAITING
Exception in thread "main thread" java.lang.ArithmeticException: / by zero
at threadd.writeSth(threadd.java:76)
at threadd.writeSth1(threadd.java:73)
at threadd$1.run(threadd.java:27)
at java.lang.Thread.run(Thread.java:855)
TERMINATED
2024-09-25T13:50:09.346 5秒后重启
RUNNABLE
2024-09-25T13:50:15.361 1
RUNNABLE
2024-09-25T13:50:16.365 2
RUNNABLE
2024-09-25T13:50:17.368 3
RUNNABLE
2024-09-25T13:50:18.374 4
RUNNABLE
2024-09-25T13:50:19.377 5
RUNNABLE
2024-09-25T13:50:20.381 6
RUNNABLE
2024-09-25T13:50:21.387 7
RUNNABLE
2024-09-25T13:50:22.392 8
RUNNABLE
2024-09-25T13:50:23.395 9
RUNNABLE
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at threadd.writeSth(threadd.java:76)
at threadd.writeSth1(threadd.java:73)
at threadd$1.run(threadd.java:27)
at java.lang.Thread.run(Thread.java:855)
TERMINATED
2024-09-25T13:50:25.406 5秒后重启
总结
- 核心代码是先定义一个thread变量,然后有异常的时候又实例化重新赋值
final Thread[] thread = {new Thread(runnable,"main thread")};
thread[0].start();
if (!thread[0].isAlive()) {
System.out.println(LocalDateTime.now()+" 5秒后重启");
Thread.sleep(5000);
thread[0] = new Thread(runnable);
thread[0].start();
}
- 不能在检测到线程的时候直接thread.start(),因为线程的生命周期已经没有,需要重新实例化,如果使用如下代码就会报错
final Thread[] thread = {new Thread(runnable,"main thread")};
thread[0].start();
if (!thread[0].isAlive()) {
System.out.println(LocalDateTime.now()+" 5秒后重启");
Thread.sleep(5000);
thread[0].start();
}
- 其实最好的办法还是要对异常进行捕获,这也是最基本的