定时任务记录

         我的需求是间隔1s,去执行我的Thread,无论上次是否成功失败,间隔1s后,就要去执行。

public class ThreadTimerExecutor {

    public static ScheduledThreadPoolExecutor threadPoolExecutor;

    public static final String THREAD_NAME = "set-timer-%s";

    static {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(ThreadTimerExecutor.THREAD_NAME).build();
        ThreadTimerExecutor.threadPoolExecutor = new ScheduledThreadPoolExecutor(2, namedThreadFactory);
    }

    /**
     * 设置定时执行
     *
     * @param runnable
     * @param delay
     */
    public static void setSchedule(Runnable runnable, Long delay){
        threadPoolExecutor.scheduleAtFixedRate(runnable, 0, delay, TimeUnit.MILLISECONDS);
    }

}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit)

参数对应含义:command为被执行的线程;initialDelay为初始化后延时执行时间;period为两次开始执行最小间隔时间;unit为计时单位。 

        业务逻辑处理间隔时间小于1000。

// 大致代码
public class Test {
    public static Long readTimeInterval = Calendar.getInstance().getTimeInMillis();
    public static void main(String[] args) {
        setSchedule(() -> {
            long nowTime = Calendar.getInstance().getTimeInMillis();
            long subTime = nowTime - readTimeInterval;
            // 这里的1_000和下面period联动才能达到效果
            if (subTime >= 1000) {
                readTimeInterval = nowTime;
                System.out.println("subTime: " + subTime);
                try {
                    // 模拟业务处理
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, 1000L);
    }

}

日志: 

23:08:21.355 [set-timer-8] INFO   subTime: 1000
23:08:22.356 [set-timer-8] INFO   subTime: 1002
23:08:24.344 [set-timer-8] INFO   subTime: 1988
23:08:25.351 [set-timer-3] INFO   subTime: 1007
23:08:26.352 [set-timer-3] INFO   subTime: 1001
23:08:27.355 [set-timer-3] INFO   subTime: 1003
23:08:29.343 [set-timer-3] INFO   subTime: 1988
23:08:30.351 [set-timer-3] INFO   subTime: 1008
23:08:32.343 [set-timer-3] INFO   subTime: 1992

        若业务处理时间大于等于设置的period间隔时间附近值时,时间就会很平均

// 大致代码
public class Test {
    public static Long readTimeInterval = Calendar.getInstance().getTimeInMillis();
    public static void main(String[] args) {
        setSchedule(() -> {
            long nowTime = Calendar.getInstance().getTimeInMillis();
            long subTime = nowTime - readTimeInterval;
            if (subTime >= 1000) {
                readTimeInterval = nowTime;
                System.out.println("subTime: " + subTime);
                try {
                    // 模拟业务处理
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, 1000L);
    }

}

日志: 

23:38:22.489 subTime: 1026
23:38:23.492 subTime: 1075
23:38:24.495 subTime: 1002
23:38:25.496 subTime: 1002
23:38:26.501 subTime: 1005
23:38:27.505 subTime: 1004
23:38:28.511 subTime: 1006
23:38:29.517 subTime: 1006
23:38:30.523 subTime: 1006
23:38:31.528 subTime: 1005

        若把逻辑处理时间再加倍加大,时间subTime也会被放大。

         scheduleAtFixedRate这个方法实测下来发现设置的周期period时间,去执行调用,但是实际并不是按照周期period去做,当业务处理时间小于周期period时间有时会间隔2s,业务处理时间大于等于周期period附近值时,时间间隔就很平均。

public class ThreadTimerExecutor {

    public static ScheduledThreadPoolExecutor threadPoolExecutor;

    public static final String THREAD_NAME = "set-timer-%s";

    static {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(ThreadTimerExecutor.THREAD_NAME).build();
        ThreadTimerExecutor.threadPoolExecutor = new ScheduledThreadPoolExecutor(2, namedThreadFactory);
    }

    /**
     * 设置定时执行
     *
     * @param runnable
     * @param delay
     */
    public static void setSchedule(Runnable runnable, Long delay){
        threadPoolExecutor.scheduleWithFixedDelay(runnable, 0, delay, TimeUnit.MILLISECONDS);
    }

}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit)
参数对应含义:command为被执行的线程;initialDelay为初始化后延时执行时间;delay为前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间);unit为计时单位。
// 大致代码
public class Test {
    public static Long readTimeInterval = Calendar.getInstance().getTimeInMillis();
    public static void main(String[] args) {
        setSchedule(() -> {
            long nowTime = Calendar.getInstance().getTimeInMillis();
            long subTime = nowTime - readTimeInterval;
            // 这里的1_000和下面period联动才能达到效果
            if (subTime >= 1000) {
                readTimeInterval = nowTime;
                System.out.println("subTime: " + subTime);
                try {
                    // 模拟业务处理
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }, 1000L);
    }

}

        日志: 

 00:28:33.353 subTime: 1300
00:28:34.558 subTime: 1205
00:28:35.764 subTime: 1207
00:28:36.971 subTime: 1207
00:28:38.174 subTime: 1202
00:28:39.382 subTime: 1209
00:28:40.589 subTime: 1207
00:28:41.800 subTime: 1211
00:28:43.009 subTime: 1209
00:28:44.215 subTime: 1206

scheduleWithFixedDelay方法,他会把业务处理时间+delay时间,算在一起,他就更加不是设置的间隔时间执行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值