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);

猜你喜欢

转载自www.cnblogs.com/csuliujia/p/9939517.html