zoukankan      html  css  js  c++  java
  • 定时器与系统时间(续)

    额外问题处理:

    --------------------------------------------------------------------------------

    13) 定时器之外的一些处理
        a) window环境下,定时器通知执行定时任务的时间点可能误差1毫秒;Linux环境也有类似情况,但是误差频率低很多(只是在指定时间点前后1毫秒误差,心跳步长不差)
            可能的影响:
                以每秒任务为例, 10:00:00.000 TaskA -> 10:00:00.999 TaskB -> 10:00:02.000 TaskC -> 10:00:03.001 TaskD
                会导致第2个任务(TaskB)丢失, 因为步长是1秒钟 + 抹去毫秒计算
            代码解决方案:
                定时器初始时间设置为 XX:XX:XX:500,以两秒的中间段为起点开始心跳,这样误差1毫秒时候,抹去毫秒不影响正常定时器执行

        Calendar cal = Calendar.getInstance();
        int millis = cal.get(Calendar.MILLISECOND);
        int delay = (1500 - millis) % 1000;        // 下个0.5秒开始运行(定时器偶尔会前后误差1毫秒)            
        timerService.scheduleAtFixedRate(new Runnable() {..}, delay, TIMER_STEP, TimeUnit.MILLISECONDS);

        b) 线程池启动,大概会延迟200毫秒后才开始心跳

            没有多大不良影响
        c) 心跳时间点未 XX:XX:XX:500, 正常情况下没有问题。
            问题是每小时同步一次服务器系统时间,可能依然导致心跳时间点押到 XX:XX:XX:000 上,从而引起问题a),当然这个概率极低
            可以考虑心跳时长为 100毫秒
        d) 任务执行接口传入当前时间作为参数
            定时器(心跳)线程,定时挑选符合执行条件的任务,扔到任务池去执行。
            因为任务执行时间过长、任务锁、线程池资源不足等条件导致的任务内部log时间不符合要求是任务本身的事情,反正定时器通知你了,不用纠结定时器问题
        e) 任务有唯一id,防止重复添加任务, 一次性任务没有Id
            任务基类对id做了处理,加了统一前缀,方便log跟踪

    定时任务优化:

    --------------------------------------------------------------------------------

    14) 现在定时器定时执行任务的功能已经完成:我在指定的时间通知你做指定的任务。不过总有一些奇怪的任务,用这样更简单的语言不方便表达。
        比如,每隔10分钟统计一次在线人数。
        当前接口可以处理,不过感觉非常笨拙:

            regPerHourTask (0, 0, TaskA);
            regPerHourTask (10, 0, TaskA);
            regPerHourTask (20, 0, TaskA);
            regPerHourTask (30, 0, TaskA);
            regPerHourTask (40, 0, TaskA);
            regPerHourTask (50, 0, TaskA);

        当然也可以尝试

            regPerMinuteTask (0, new Task () {
                每10次执行1次,忽略9次
            });

        于是抽象出一个固定分钟执行的任务,你告诉我你要几分钟执行一次,然后实现我的执行接口就是了

        这样又产生了一个新的问题,比如,每隔5分钟统计一次在线人数。

            2014-12-20 13:58:12,503 INFO 人数为N // 当前log是
            2014-12-20 13:03:12,503 INFO 人数为N
            2014-12-20 13:08:12,503 INFO 人数为N
            2014-12-20 13:13:12,503 INFO 人数为N
            2014-12-20 13:18:12,503 INFO 人数为N
            2014-12-20 13:22:53,321 INFO 人数为N // 重启服务器后:
            2014-12-20 13:27:53,321 INFO 人数为N
            2014-12-20 13:32:53,321 INFO 人数为N
            2014-12-20 13:37:53,321 INFO 人数为N

        看起来有点小晕

        解决方案:
            固定分钟执行的任务, 初始增加一个 baseTime 参数, 时间计算依赖 baseTime 去选择执行或忽略

            2014-12-20 13:00:00,000 INFO 人数为N  // 当前log是
            2014-12-20 13:05:00,000 INFO 人数为N
            2014-12-20 13:10:00,000 INFO 人数为N
            2014-12-20 13:15:00,000 INFO 人数为N
            2014-12-20 13:20:00,000 INFO 人数为N
            2014-12-20 13:30:00,000 INFO 人数为N  // 重启服务器后
            2014-12-20 13:35:00,000 INFO 人数为N
            2014-12-20 13:40:00,000 INFO 人数为N
            2014-12-20 13:45:00,000 INFO 人数为N

        这样 grep 出来log对时间就舒服多了

    定时任务优化(二):

    --------------------------------------------------------------------------------

    15) 先做了到点通知功能,后来额外加了定时通知功能;突然发现,这个只是个正常的任务功能,还有不正常的情况。
        比如,我们需要远程请求加载数据,可能这数据相对重要一些,但是只要一次取对的数据就可以了,问题它可能失败。
        换个描述方式就是,我需要去其它地方拿数据,直到拿到为止。当然现在的定时器也支持这个任务,尽管不友好:
            注册一个每分钟任务,如果发现任务完成了,就移除。
        但是实际问题可能更复杂一些:
            如果任务执行失败,我就5秒后再执行一次;
            如果再失败,我就30秒后执行一次;
            如果再失败,就3分钟后执行;
            如果再失败,就算了,不能无休止执行;也可能过了一定期限后,执行成功也没有意义
        在自己的任务里可以自行处理类似逻辑,不过这也是可以抽象的,于是需要增加一个固执的任务,失败后休息一定时间再执行
        规定的失败次数(可尝试次数)用完后,没有完成也不再执行了
        这里的需要通知任务执行的时候,执行函数是有成功与否的返回值。

    总结

    --------------------------------------------------------------------------------

    16) 总结
        a) 定时器通知【可以执行的指定任务】了
        b) 定时器【定时】通知【可以执行的指定任务】了
        c) 定时器【多次】通知【需要执行成功的指定任务】了
        d) 定时器顺便解决了服务器系统时间问题

  • 相关阅读:
    过河卒(Noip2002)
    暑假学习日记2013/7/18
    暑假学习日记2013/7/16
    iOS中利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G) by徐文棋
    隐藏键盘的N种方法
    cell重用
    关于viewControllers之间的传值方式
    iOS开发之工欲善其事,必先利其器
    NSLog输出格式及随机数
    iOS团队代码规范
  • 原文地址:https://www.cnblogs.com/lixingxing/p/4188956.html
Copyright © 2011-2022 走看看