本文原地址來自於我的個人博客: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的思路和解決方案。