当前位置:   article > 正文

ScheduledExecutorService - 定时周期执行任务

scheduledexecutorservice

ScheduleExecutorService接口中有四个重要的方法,其中scheduleAtFixedRatescheduleWithFixedDelay在实现定时程序(每隔一段时间执行一次)时比较方便。

接口中四个方法如下:

该接口中前两个方法只会执行一次,后两个方法会定时循环执行。

 — 三个方法简介—

1. ScheduledFuture<?> schedule(
        Runnable command,
        long delay,
        TimeUnit unit
)

定义:在给定的延时之后,创建并执行一个启动一次性动作。
参数:
参数一(Runnable):命令执行的任务。
参数二(delay)       :延迟执行的时间。 
参数三(TimerUnit):延时蚕食的时间单位。

例:
在若依框架中,封装了一个异步打印日志的类,就是用到了schedule()方法:

  1. public class AsyncManger{
  2. // ··· ···
  3. // 从ioc容器中获取 bean,注:SpringUtils也是若依框架封装的,通过名称来获取bean(可
  4. // 以通过首字母小写形式根据名称来获取ioc容器中的bean)
  5. private ScheduledExecutorService executor = SpringUtils.getBean("scheduledExecutorService");
  6. // 延迟20毫秒,执行任务类,在任务类中会去 insert 信息。
  7. public viod execute(TimerTask task) {
  8. executor.schedule(task, 20, TimeUnit.MILLISECONDS);
  9. }
  10. }

2. ScheduledFuture<?> scheduleAtFixedRate(
        Runnable command,
        long initialDelay,
        long period,
        TimeUnit unit
)

定义:创建并执行一个周期性的操作。

参数:
command:执行线程。
initialDelay:初始化延时。
period:两次开始执行最小间隔时间。
unit:计时单位。

3. ScheduledFuture<?> scheduleWithFixedDelay(
        Runnable command,
        long initialDelay,
        long delay,
        TimeUnit unit
)

定义:创建并执行一个周期性的操作。

参数:
command:执行线程。
initialDelay:初始化延时。
period:前一次执行结束到下一次执行开始的间隔时间(间隔执行延迟时间)。
unit:计时单位。

 

 — 功能 —

1. 每隔多长时间重新执行一次任务。
初始延时0毫秒,每隔1000毫秒重新执行一次任务:

  1. /**
  2. * 以固定周期频率执行任务
  3. */
  4. public class Test {
  5. public static void main(String[] args) {
  6. ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
  7. scheduledExecutorService.scheduleAtFixedRate(
  8. Test.timerTask(), 0, 1000, TimeUnit.MILLISECONDS
  9. );
  10. }
  11. public static TimerTask timerTask () {
  12. return new TimerTask() {
  13. @Override
  14. public void run() {
  15. System.out.println("执行了");
  16. }
  17. };
  18. }
  19. }

问题:
如果要执行的任务时间大于间隔时间,会如何处理呢?
其实当执行任务的时间大于我们指定的间隔时间时,它并不会在指定间隔时开辟一个新的线程并发执行这个任务,而是等待该线程执行完毕。
源码注释:
If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
如果此任务的任何执行时间超过其周期,则后续执行可能开始较晚,但不会并发执行。  

关于创建线程池:
创建一个线程池,该线程池可以调度命令在给定的延时后运行或定期执行。
参数:corePoolSize - 保持在池中的线程数,即使他们是空闲的。
返回:新创建的调度线程池。
抛出:如果corePoolSize < 0 ,IllegalArgumentException 

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);

关于 IllegalArgumentException 异常:

Illegal Argument Exception 非法参数异常。

2. 按照指定频率间隔执行某个任务。
初始化延时0ms开始,本次执行结束后延迟1000ms开始下次执行,注意:必须等到本次任务执行完毕才能开始延时且开始下一次任务执行。

  1. /**
  2. * 以固定延迟时间进行执行
  3. * 本次任务执行完成后,需要延迟设定的延迟时间,才会执行新的任务
  4. * 下边代码,延时0毫秒开始执行timerTask() 方法,Thread.sleep(2000) 暂停2000毫秒,之后才开始
  5. * 延时1000毫秒,执行下一次任务。
  6. */
  7. public class Test {
  8. public static void main(String[] args) {
  9. ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
  10. scheduledExecutorService.scheduleWithFixedDelay(
  11. Test.timerTask(), 0, 1000, TimeUnit.MILLISECONDS
  12. );
  13. }
  14. public static TimerTask timerTask () {
  15. return new TimerTask() {
  16. @Override
  17. public void run() {
  18. try {
  19. Thread.sleep(2000);
  20. } catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. System.out.println("执行了");
  24. }
  25. };
  26. }
  27. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/83852
推荐阅读
相关标签
  

闽ICP备14008679号