java线程检测_Java——检测其他线程的状态以及启动已死亡的线程

这次这个的思路是在主类中维护一个map,map的key是线程名,value是线程的状态,然后创建周期执行的线程通过检测这个map来判断进程的状态,如果有死亡的进程就把该进程启动。

首先是主类,这里的main方法中为了执行结果简单易懂 ,先是初始化了一个长度为2的newFixedThreadPool线程池,然后提交了2个任务(这个任务类下面会有介绍),然后启动监控线程,这个监控线程也是一会介绍,其他方法的作用注释写得也很清楚:

public classTest {/**Log4j 初始化*/

private static final Logger logger = LoggerFactory.getLogger(Test.class);/**标志线程存活的变量*/

public static final int THREAD_STATUS_ALIVE = 1;/**标志线程死亡的变量*/

public static final int THREAD_STATUS_DEAD = 0;/**记录每个线程的状态的map*/

private static HashMap threadStatesMap = new HashMap();/**线程池的长度*/

private static intthreadPoolLength;/**创建固定长度的线程池*/

private staticExecutorService executor;public static voidmain(String[] args) {/**初始化线程池*/executor= Executors.newFixedThreadPool(2);/**提交Task给线程池*/

for(int i = 1; i <= 2; i++){

executeToPool(newEtlTask(i));

}

Monitor monitor= newMonitor();/**启动检测线程*/monitor.start();

}/*** 根据线程名,更新线程的状态

*@paramthreadName

*@paramstatus*/

public synchronized static voidalterThreadStatesMap(String threadName,Integer status){

threadStatesMap.put(threadName,status);

}/*** 返回ThreadStatesMap的长度

*@return

*/

public static intgetThreadStatesMapSize(){returnthreadStatesMap.size();

}/*** 返回key对应ThreadStatesMap的value

*@paramkey

*@returnThreadStatesMapValueByKey*/

public static intgetThreadStatesMapValueByKey(String key){returnthreadStatesMap.get(key);

}/*** 提交任务给线程池

*@parametlTask*/

public static voidexecuteToPool(EtlTask etlTask){

executor.execute(etlTask);

}

}

然后创建一个会报异常的测试类(id每一秒减一次1,到0的时候抛异常):

/*** 测试线程*/

classtestThread {private static Logger logger = LoggerFactory.getLogger(testThread.class);public static void start(int id) throwsException{

id= id + 5;while (true){try{

Thread.sleep(1000);

}catch(Exception e){

e.printStackTrace();

}

id= id - 1;if(id == 0){//id每一秒减一次1,到0的时候抛异常

throw newException();

}

logger.debug(Thread.currentThread().getName()+ " is running result = " +id );

}

}

}

然后创建一个执行上面测试任务的任务类,这里在第一次被启动的时候会设置好该任务类的名字,将主类中的map中线程名对应的value设置为THREAD_STATUS_ALIVE,然后开始执行上面的测试任务,如果有异常的话会将主类中的map中线程名对应的value设置为THREAD_STATUS_DEAD:

/*** 任务线程*/

class EtlTask implementsRunnable{/**组ID*/

private intgroupid ;/**初始化组ID*/EtlTask(intgroupid){this.groupid =groupid;

}public voidrun() {/**设置线程名*/Thread.currentThread().setName("G" +groupid);/**设置线程的 运行状态为THREAD_STATUS_ALIVE 在ThreadStatesMap中*/Test.alterThreadStatesMap(Thread.currentThread().getName(),Test.THREAD_STATUS_ALIVE);try{/**将组ID传入,执行任务*/

testThread.start(groupid);

}catch(Exception e ){/**出现异常 设置线程的 运行状态为THREAD_STATUS_DEAD 在ThreadStatesMap中*/Test.alterThreadStatesMap(Thread.currentThread().getName(),Test.THREAD_STATUS_DEAD);

}

}

}

最后就是监控类,这个类就是在遍历主类中的map,有死亡的线程就启动该线程。

/*** 监控线程*/

class Monitor extendsThread{private static final Logger logger = LoggerFactory.getLogger(Monitor.class);public voidrun() {while(true){try{

Thread.sleep(5000);//监控线程阻塞5秒后运行

}catch(Exception e){

e.printStackTrace();

}

logger.debug("Current total [" + Test.getThreadStatesMapSize() +"] threads");/**线程存活数*/

int alives = 0;/**线程死亡数*/

int deads = 0;/**遍历ThreadStatesMap 计算线程存活数和死亡数*/

for(int i = 1;i <= Test.getThreadStatesMapSize();i++){if(Test.getThreadStatesMapValueByKey("G" + i) ==Test.THREAD_STATUS_ALIVE){

alives++;

}else{

deads++;

}

}

logger.debug("Current the number of threads alive is [" + alives +"]");

logger.debug("Current the number of threads dead is [" + deads +"]");/**如果死亡线程数大于0 就启动已经死亡的线程*/

if(deads > 0) {/**遍历ThreadStatesMap 将死亡的线程启动*/

for (int i = 1; i <= Test.getThreadStatesMapSize(); i++) {if (Test.getThreadStatesMapValueByKey("G" + i) ==Test.THREAD_STATUS_DEAD) {/**向线程池提交任务*/Test.executeToPool(newEtlTask(i));

logger.debug("Thread G" + i + "已被启动");

}

}

}

}

}

}

效果:

2018-08-02 16:24:31,649 - G2 is running result = 6

2018-08-02 16:24:31,655 - G1 is running result = 5

2018-08-02 16:24:32,653 - G2 is running result = 5

2018-08-02 16:24:32,656 - G1 is running result = 4

2018-08-02 16:24:33,653 - G2 is running result = 4

2018-08-02 16:24:33,656 - G1 is running result = 3

2018-08-02 16:24:34,653 - G2 is running result = 3

2018-08-02 16:24:34,656 - G1 is running result = 2

2018-08-02 16:24:35,635 - Current total [2] threads2018-08-02 16:24:35,635 - Current the number of threads alive is [2]2018-08-02 16:24:35,635 - Current the number of threads dead is [0]2018-08-02 16:24:35,654 - G2 is running result = 2

2018-08-02 16:24:35,657 - G1 is running result = 1

2018-08-02 16:24:36,654 - G2 is running result = 1

2018-08-02 16:24:40,635 - Current total [2] threads2018-08-02 16:24:40,635 - Current the number of threads alive is [0]2018-08-02 16:24:40,635 - Current the number of threads dead is [2]2018-08-02 16:24:40,635 -Thread G1已被启动2018-08-02 16:24:40,635 -Thread G2已被启动2018-08-02 16:24:41,635 - G2 is running result = 6

2018-08-02 16:24:41,635 - G1 is running result = 5

2018-08-02 16:24:42,636 - G1 is running result = 4

2018-08-02 16:24:42,636 - G2 is running result = 5

2018-08-02 16:24:43,636 - G2 is running result = 4

2018-08-02 16:24:43,636 - G1 is running result = 3

2018-08-02 16:24:44,637 - G2 is running result = 3

2018-08-02 16:24:44,637 - G1 is running result = 2

2018-08-02 16:24:45,636 - Current total [2] threads2018-08-02 16:24:45,636 - Current the number of threads alive is [2]2018-08-02 16:24:45,636 - Current the number of threads dead is [0]2018-08-02 16:24:45,637 - G1 is running result = 1

2018-08-02 16:24:45,637 - G2 is running result = 2

2018-08-02 16:24:46,637 - G2 is running result = 1

2018-08-02 16:24:50,636 - Current total [2] threads2018-08-02 16:24:50,636 - Current the number of threads alive is [0]2018-08-02 16:24:50,636 - Current the number of threads dead is [2]2018-08-02 16:24:50,636 -Thread G1已被启动2018-08-02 16:24:50,636 -Thread G2已被启动2018-08-02 16:24:51,637 - G2 is running result = 6

2018-08-02 16:24:51,637 - G1 is running result = 5

2018-08-02 16:24:52,637 - G1 is running result = 4

2018-08-02 16:24:52,637 - G2 is running result = 5Process finished with exit code-1

从控制台的输出日志可以看到,两个线程的结果到0的时候死亡了,然后会被监控进程启动。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值