記錄ScheduledExecutorService使用中不工作情況

本文原地址來自於我的個人博客: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中有這麼一段話。

QQ截圖20151217092815.jpg

如果任務的任意執行遇到異常,就會取消後續執行。

這句話非常重要,也給了我解決問題的思路。那肯定是我的run方法裏面的代碼報錯了,但是我又沒有看見後臺有報錯,只要設置一個線程默認未捕獲異常的處理handler。

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

            @Override
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();
            }
        });

該代碼放置在線程開啓前面。再次運行以後,果斷髮現了問題。

原來是Hibernate裏面session中事務導致報錯的問題,錯誤如何處理就不詳細講了,解決報錯之後,代碼就能夠正常運行。

以上文章由於記錄處理這個bug的思路和解決方案。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章