小记:另起一个线程执行业务代码时出现异常后就停止执行问题

一、现象

java项目中,在启动时会自动开启一个线程去redis中循环读取标识是否有任务需要执行,有一天线上突然出现异常,并且也没有找到相关的异常日志,排查发现是这个线程没有正常执行,后来经过日志仔细排查,发现redis曾出现过异常,服务端日志中找到Could not get a resource from the pool,只出现了2分钟,后redis又正常了,经过观察也是出现这个异常后,线程就不能正常执行了。

二、解决

在循环代码中加入try..catch进行异常捕获,避免出现异常线程停止执行。优化后的伪代码如下。

@PostConstruct
public void task(){
	//另起线程执行,避免阻塞无法启动
	ExecutorService executorService = Executors.newFixedThreadPool(1);
	executorService.submit(()->{
		while (true){
			try {
				//循环读取redis中是否有待执行任务
				Set<Object> taskSet = RedisUtil.redisTemplate.opsForZSet().rangeByScore(taskName,0,System.currentTimeMillis(),0,1);
				if(taskSet==null||taskSet.isEmpty()){
					//休眠5秒后再次执行
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						logger.error("task thread sleep error",e);
					}
					continue;
				}
				//发送kafka异步消费处理
				Object it = taskSet.iterator().next();
				//删除成功
				if(RedisUtil.redisTemplate.opsForZSet().remove(delayQueueName,it)>0){
					//执行业务代码
				}
			} catch (Exception e) {
				try {
					//如果出现异常,线程睡眠5秒
					Thread.sleep(5000);
				} catch (InterruptedException ex) {
					logger.error("task thread sleep error",ex);
				}
				logger.error("task exec error",e);
			}
		}
	});
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值