真不知道大家有没有遇到过这种问题:
1.任务处理一半,线程挂了怎么办?
2.线程池有没有补齐线程的功能?
这里举一个小demo,用来处理线程死掉,重启线程处理任务。
并未使用多个线程,而是使用一个线程来处理:
在抓去到异常的时候,在catch中将该任务重新调用。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 即使线程出现问题,可以通过线程池管理线程,重新启动线程来执行任务
*
* 这里展示的是一个计算1+2+...100的计算,在加到50的时候抛出异常,然后再catch中重新启动一个线程继续执行任务
*
*/
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new Runnable() {
int count = 1;
int sum = 0;
public void run() {
while (true){
try {
Thread.sleep(10);
if(count == 101){
break;
}
if (count == 50){
sum = sum + count;
count ++;
throw new RuntimeException("我是异常");
}
sum = sum + count;
System.out.println("##count:"+count+",sum:"+sum);
count ++;
}catch (Exception e){
e.printStackTrace();
//注意这个地方
System.out.println("重启一个线程,继续执行");
executorService.execute(this);
}
}
}
});
}
}
执行结果:
##count:1,sum:1
##count:2,sum:3
##count:3,sum:6
##count:4,sum:10
##count:5,sum:15
##count:6,sum:21
##count:7,sum:28
##count:8,sum:36
##count:9,sum:45
##count:10,sum:55
##count:11,sum:66
##count:12,sum:78
##count:13,sum:91
##count:14,sum:105
##count:15,sum:120
##count:16,sum:136
##count:17,sum:153
##count:18,sum:171
##count:19,sum:190
##count:20,sum:210
##count:21,sum:231
##count:22,sum:253
##count:23,sum:276
##count:24,sum:300
##count:25,sum:325
##count:26,sum:351
##count:27,sum:378
##count:28,sum:406
##count:29,sum:435
##count:30,sum:465
##count:31,sum:496
##count:32,sum:528
##count:33,sum:561
##count:34,sum:595
##count:35,sum:630
##count:36,sum:666
##count:37,sum:703
##count:38,sum:741
##count:39,sum:780
##count:40,sum:820
##count:41,sum:861
##count:42,sum:903
##count:43,sum:946
##count:44,sum:990
##count:45,sum:1035
##count:46,sum:1081
##count:47,sum:1128
##count:48,sum:1176
##count:49,sum:1225
java.lang.RuntimeException: 我是异常
at com.threadpool.SingleThreadExecutor$1.run(SingleThreadExecutor.java:29)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
重启一个线程,继续执行
##count:51,sum:1326
##count:52,sum:1378
##count:53,sum:1431
##count:54,sum:1485
##count:55,sum:1540
##count:56,sum:1596
##count:57,sum:1653
##count:58,sum:1711
##count:59,sum:1770
##count:60,sum:1830
##count:61,sum:1891
##count:62,sum:1953
##count:63,sum:2016
##count:64,sum:2080
##count:65,sum:2145
##count:66,sum:2211
##count:67,sum:2278
##count:68,sum:2346
##count:69,sum:2415
##count:70,sum:2485
##count:71,sum:2556
##count:72,sum:2628
##count:73,sum:2701
##count:74,sum:2775
##count:75,sum:2850
##count:76,sum:2926
##count:77,sum:3003
##count:78,sum:3081
##count:79,sum:3160
##count:80,sum:3240
##count:81,sum:3321
##count:82,sum:3403
##count:83,sum:3486
##count:84,sum:3570
##count:85,sum:3655
##count:86,sum:3741
##count:87,sum:3828
##count:88,sum:3916
##count:89,sum:4005
##count:90,sum:4095
##count:91,sum:4186
##count:92,sum:4278
##count:93,sum:4371
##count:94,sum:4465
##count:95,sum:4560
##count:96,sum:4656
##count:97,sum:4753
##count:98,sum:4851
##count:99,sum:4950
##count:100,sum:5050
顺利的执行了任务。
这里面可能有个疑问就是catch中的executorService.execute(this)。这里面的this指的是什么?
其实这里的this就是指new Runnable()的任务。其实不需要执行executorService.execute(this)也能顺利的完成
为了方便看清,将代码做一些变更。
public class SingleThreadExecutor {
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
TaskInner taskInner = new TaskInner(executorService);
System.out.println("1==>"+taskInner.getClass());
executorService.execute(taskInner);
}
static class TaskInner implements Runnable{
private ExecutorService es;
public TaskInner(ExecutorService es) {
this.es = es;
}
int count = 1;
int sum = 0;
public void run() {
while (true){
try {
Thread.sleep(10);
if(count == 101){
break;
}
if (count == 50){
sum = sum + count;
count ++;
throw new RuntimeException("我是异常");
}
sum = sum + count;
System.out.println("##count:"+count+",sum:"+sum);
count ++;
}catch (Exception e){
e.printStackTrace();
System.out.println("2==>"+this.getClass());
System.out.println("重启一个线程,继续执行");
//es.execute(this);
}
}
}
}
}
打印的结果:
1==>class com.threadpool.SingleThreadExecutor$TaskInner
2==>class com.threadpool.SingleThreadExecutor$TaskInner