1. 程式人生 > >Timer類注意事項

Timer類注意事項

Java的一個Timer物件可以執行多個Timertask任務,但是一個Timer物件本身只有一個執行緒,如果向他提交多個task,並且某個task相當耗時的話,其他的task即使到了執行時間,仍然會等之前的task執行完畢。更有問題,如果前一個task丟擲了異常導致執行緒終止,後面的task將無法執行。

 

Timer 是一種定時器工具,用來在一個後臺執行緒計劃執行指定任務,這些任務可以被執行一次,也可以被定期執行。每個 Timer 物件對應一個後臺執行緒,順序地執行所有計時器任務。如果完成某個計時器任務的時間太長,那麼它會“獨佔”計時器的任務執行執行緒,從而可能延遲後續任務的執行。對 Timer 物件最後的引用完成並且所有未處理的任務都已執行完成後,計時器的任務執行執行緒會正常終止(並且成為垃圾回收的物件)。TimerTask是一個抽象類,實現了Runable介面,它的子類代表一個可以被Timer計劃的任務。 

 

Timer類的schedule和scheduleAtFixedRate的區別:

schedule和 scheduleAtFixedRate的區別在於,schedule以固定的相對時間間隔執行,如果某一次執行被延時了,往後的執行的執行時間也會相對延時;而scheduleAtFixedRate是以絕對的時間間隔執行,如果某一次執行被延時,它的後一次執行的延時將會縮短(scheduleAtFixedRate會把已經過去的時間也作為週期執行)。schedule注重的是時間間隔的穩定,而scheduleAtFixedRate注重的是執行頻率的穩定。 

 

示例如下:

timerForDims = new Timer();

        timerForDims.scheduleAtFixedRate(new TimerTask() {

            @Override

            public void run() {

                updateDim();

            }

        }, Calendar.getInstance().getTime(), 10 * 60 * 1000);

 

        //每日3點從離線表裡讀取老使用者ID存入redis

        Calendar calendar = Calendar.getInstance();

        calendar.set(Calendar.HOUR_OF_DAY, 3);

 

        String beforeDay = TimeUtil.getBeforeDay();

        RefreshHiveOldUsers(beforeDay);

 

        timerForOldUsers = new Timer();

        timerForOldUsers.scheduleAtFixedRate(new TimerTask() {

            @Override

            public void run() {

                try {

                    RefreshHiveOldUsers(beforeDay);

                } catch (SQLException e) {

                    logger.error("RefreshOldUser: " + e.getMessage());

                }

            }

        }, calendar.getTime(), 24 * 60 * 60 * 1000);