jdk定时任务的使用

Timer

JDK内置了 java.util.Timer 类,

可以用来调度 java.util.TimerTask 任务。

可以前端页面传递定时执行的简单时间

几个重要的方法:

schedule:开始调度任务,提供了几个包装方法;
cancle:终止任务调度,取消当前调度的所有任务,正在运行的任务不受影响;
purge:从任务队列中移除所有已取消的任务;
另外,java.util.TimerTask 就是实现了 Runnable 接口,具体任务逻辑则是在 run 方法里去实现。

private static void timerTask() throws InterruptedException {
        Timer timer = new Timer();

        TimerTask timerTask = new TimerTask() {
            @Override
            public void run() {
                System.out.println("hi, 欢迎关注:Java技术栈");
            }
        };

        // 第一次任务延迟时间
        long delay = 2000;

        // 任务执行频率
        long period = 3 * 1000;

        // 开始调度
        timer.schedule(timerTask, delay, period);

        // 指定首次运行时间
// timer.schedule(timerTask, DateUtils.addSeconds(new Date(), 5), period);

        Thread.sleep(20000);

        // 终止并移除任务
        timer.cancel();
        timer.purge();
    }

这种实现方式比较简单,可以指定首次执行的延迟时间、首次执行的具体日期时间,以及执行频率,能满足日常需要。

另外,需要注意的是,Timer 是线程安全的,因为背后是单线程在执行所有任务。

Timer 也会有一些缺陷:

Timer 是单线程的,假如有任务 A,B,C,任务 A 如果执行时间比较长,那么就会影响任务 B,C 的启动和执行时间,如果 B,C 执行时间也比较长,那就会相互影响;
Timer 不会捕获异常,如果 A,B,C 任何一个任务在执行过程中发生异常,就会导致 TImer 整个定时任务停止工作;
Timer 是基于绝对时间调度的,而不是基于相对时间,所以它对系统时间的改变非常敏感;
所以,如果在使用 Timer 的过程中要注意这些缺陷,虽然可以用,但不推荐。

ScheduledExecutorService

因 Timer 有一些缺陷,所以不太建议使用 Timer,推荐使用 ScheduledExecutorService:

/**
 * Creates a thread pool that can schedule commands to run after a
 * given delay, or to execute periodically.
 * @param corePoolSize the number of threads to keep in the pool,
 * even if they are idle
 * @return a newly created scheduled thread pool
 * @throws IllegalArgumentException if {@code corePoolSize < 0}
 */
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}

/**
 * Creates a thread pool that can schedule commands to run after a
 * given delay, or to execute periodically.
 * @param corePoolSize the number of threads to keep in the pool,
 * even if they are idle
 * @param threadFactory the factory to use when the executor
 * creates a new thread
 * @return a newly created scheduled thread pool
 * @throws IllegalArgumentException if {@code corePoolSize < 0}
 * @throws NullPointerException if threadFactory is null
 */
public static ScheduledExecutorService newScheduledThreadPool(
        int corePoolSize, ThreadFactory threadFactory) {
    return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}

上了线程池,每个调度任务都会分配到线程池中的某一个线程去执行,任务就是并发调度执行的,任务之间互不影响。

几个重要的调度方法:

schedule:只执行一次调度;
scheduleAtFixedRate:按固定频率调度,如果执行时间过长,下一次调度会延迟,不会同时执行;
scheduleWithFixedDelay:延迟调度,上一次执行完再加上延迟时间后执行;
另外,可以看出,任务是支持 Runnable 和 Callable 调度的。

/**
 * 线程池定时任务
 * 这是一个按固定频率调度的任务,创建了 10 个核心线程数,首次执行延迟 2 秒,后续每 3 秒执行一次。
 * 这种方式简单、好用,避免了使用 Timer 带来的各种问题,推荐使用这种实现方式。
 */
 public static void poolTask(){
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(10);

        pool.scheduleAtFixedRate(() -> {
            System.out.println("2 秒后开始执行,每 3 秒执行一次");
        }, 2000, 3000, TimeUnit.MILLISECONDS);

        pool.schedule(() -> {
            System.out.println("2 秒后开始执行,我只执行一次");
        }, 2000, TimeUnit.MILLISECONDS);

        pool.scheduleWithFixedDelay(() -> {
            System.out.println("hi?????");
        }, 2000, 3000,TimeUnit.MILLISECONDS);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

研程序笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值