本文原地址来自于我的个人博客:www.endless365.com,希望得到各位的关注。
本文详细地址出自于:http://www.endless365.com/article/get?type=tec&id=154
由于本博客存在一个自己的IP统计功能,使用了淘宝API查询IP的归属地,由于淘宝API查询IP归属地存在访问速度限制问题,导致本博客在插入用户记录的时候查询归属地特别的慢,所有考虑使用多线程去处理,但是写了代码以后才发现我的阿里云服务器是单核的,多线程好像没什么卵用,好吧,又想了一想,考虑使用一个定时器在晚上某个时候执行。接下来问题就出来了。。。
先上我的代码:
ScheduledExecutorService schedule = Executors.newSingleThreadScheduledExecutor(); schedule.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { System.out.println("into updateUserActivityIP=========="+DateTool.getCurrentTimeCN()); userActivityService.updateAllUserActivity(); } catch (Exception e) { e.printStackTrace(); } } }, 0, 30, TimeUnit.MINUTES);
当启动tomcat服务器以后,每隔30分钟执行一次更新user activity记录中ip归属地的信息,在测试的过程中发现,into updateUserActivityIP的打印每次都只执行了一次,这个郁闷啊,查来查去找不到问题的原因。然后就另外写了一个定时器的demo
/** * * @author sunny */ public class ScheduleTest { public static int i=0; public static void main(String[] args) { ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor(); pool.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { i++; System.out.println("i="+i); } catch (Exception ex) { Logger.getLogger(ScheduleTest.class.getName()).log(Level.SEVERE, null, ex); } } }, 1, 1, TimeUnit.SECONDS); } }
发现这个Demo没有任何的问题,好吧,只能去查查JDK的API看在什么情况下会导致ScheduledExecutorService不工作。发现JDK中有这么一段话。
如果任务的任意执行遇到异常,就会取消后续执行。
这句话非常重要,也给了我解决问题的思路。那肯定是我的run方法里面的代码报错了,但是我又没有看见后台有报错,只要设置一个线程默认未捕获异常的处理handler。
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { e.printStackTrace(); } });
该代码放置在线程开启前面。再次运行以后,果断发现了问题。
原来是Hibernate里面session中事务导致报错的问题,错误如何处理就不详细讲了,解决报错之后,代码就能够正常运行。
以上文章由于记录处理这个bug的思路和解决方案。