一个try{}catch位置引发的血案


  多线程是个坑,这话一点不假。最近在使用多线程异步发送邮件的时候就掉坑了。


 老代码如下:


  private static class SendExecutor extends Thread {


public void run() {
init();
if (null != queue) {

                              try {
while (true) {
EmailInfo email = queue.poll(300, TimeUnit.SECONDS);
if (null != email) {
if (log.isInfoEnabled()) {
log.info("send email , targetEmail : " + email.getTargetEmail() + " subject : " + email.getSubject());
}
if (log.isDebugEnabled()) {
log.debug("send email , targetEmail : " + email.getTargetEmail() + " subject : " + email.getSubject() + "  content "
+ email.getContent());
}
sendMail(email.getContent(), email.getSubject(), email.getTargetEmail());
}

                                 }
} catch (Exception e) {
log.error("", e);
}

}
}
}


queue采用的是LinkedBlockingQueue, 粗略的看,是否没有问题(我也是这样的)。 但代码在生产环境上出现了bug。

客户反应,邮件没有接受到. 看日志,代码也没有发现问题。最后在日志中发现了一个错误日志,才提醒了我问题出现的地方。


  问题出现在try{}catch的位置在循环外,因此,如果出现异常,while将跳出,线程将完成,后续就没有消费者执行发送任务。

 查看系统日志发现,因为系统中有部分老用户,老用户的邮箱地址不规范,例如,有一个用户的邮箱地址是 “1”,导致在执行sendMail()的时候,出现异常。

修改这个bug其实也很简单,将try{}catch防止在while里面就行,当然,在进入队列之前,检查邮箱是否为合格的邮箱地址很有必要.


修改后的代码如下:


private static class SendExecutor extends Thread {


public void run() {
init();
if (null != queue) {
while (true) {
try {
EmailInfo email = queue.poll(300, TimeUnit.SECONDS);
if (null != email) {
if (log.isInfoEnabled()) {
log.info("send email , targetEmail : " + email.getTargetEmail() + " subject : " + email.getSubject());
}
if (log.isDebugEnabled()) {
log.debug("send email , targetEmail : " + email.getTargetEmail() + " subject : " + email.getSubject() + "  content "
+ email.getContent());
}
sendMail(email.getContent(), email.getSubject(), email.getTargetEmail());
}
} catch (Exception e) {
log.error("", e);
}
}
}
}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值