記錄ScheduledExecutorService使用中不工作情況
阿新 • • 發佈:2019-01-30
本文原地址來自於我的個人部落格: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的思路和解決方案。