ScheduledThreadPoolExecutor 定时任务

这篇具有很好参考价值的文章主要介绍了ScheduledThreadPoolExecutor 定时任务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录
  • ScheduledThreadPoolExecutor
    • 一、概述
    • 二、常用方法
      • 1、schedule 方法
      • 2、scheduleAtFixedRate方法
      • 3.scheduleWithFixedDelay方法
    • 三、ScheduledExecutorService的创建方式

ScheduledThreadPoolExecutor

一、概述

java 中ScheduledExecutorService接口是基于线程池设计的定时任务类,每个调度任务都会分配到线程池中的一个线程去执行,也就是说,任务是并发执行,互不影响。
其中的一个实现类是ScheduledThreadPoolExecutor

(1)>ScheduledThreadPoolExecutor实现ScheduledExecutorService接口,实现了一些定时任务处理的方法。

(2)>ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,可以通过线程池进行任务的管理和调度。

二、常用方法

1、schedule 方法

该方法的作用是提交一个延迟执行的任务,任务从提交时间算起延迟单位unit的deplay时间后执行,提交的不是周期任务,任务只会执行一次

ScheduledFuture<?> schedule(Runnable var1, long period, TimeUnit var4);
ScheduledFuture<V> schedule(Callable<V> var1, long var2, TimeUnit var4);

参数解析:

  • Runnable 需要运行的任务
  • period 间隔时间
  • unit参数是时间单元

代码demo:

 ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
  System.out.println("当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
// 使用的Runnable 匿名函数编写的
service.schedule(() -> {
            System.out.println("我是使用schedule方法执行");
            Thread thread = Thread.currentThread();
            System.out.println("我是间隔1s执行的任务,线程名称为:" + thread.getName() + ",线程ID为:" + thread.getId() + ",当前时间:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        }, 1, TimeUnit.SECONDS);  // 延1秒后开始执行
 ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
 System.out.println("当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

service.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("我是使用schedule方法执行");
                Thread thread = Thread.currentThread();
                System.out.println("我是间隔1s执行的任务,线程名称为:" + thread.getName() + ",线程ID为:" + thread.getId() + ",当前时间:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }, 1, TimeUnit.SECONDS);  // 延1秒后开始执行
ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1);
//使用 Callable 实现,该实现有返回值,可以接收返回的数据
ScheduledFuture<Object> future = service.schedule(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                System.out.println("我是使用schedule方法执行");
                Thread thread = Thread.currentThread();
                System.out.println("我是间隔1s执行的任务,线程名称为:" + thread.getName() + ",线程ID为:" + thread.getId() + ",当前时间:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                return null;
            }
        }, 1, TimeUnit.SECONDS);// 延1秒后开始执行

        Object o = future.get();
        System.out.println(o);

输出结果为:

当前时间为:2024-03-18 14:31:01
我是使用schedule方法执行
我是间隔1s执行的任务,线程名称为:pool-1-thread-1,线程ID为:21,当前时间:2024-03-18 14:31:02

2、scheduleAtFixedRate方法

该方法相对起始时间点以固定频率调用指定的任务(fixed-rate任务)。当把任务提交到线程池并延迟initialDelay时间后开始执行任务command。然后从initialDelay+period时间点再次执行,而后在initialDelay+2*period时间点再次执行,循环往复,直到抛出异常或者调用了任务的cancel方法取消了任务,或者关闭了线程池。

参数讲解:

  • command 任务实例
  • initialDelay参数是初始化延迟时间
  • period参数是间隔时间
  • unit参数是时间单元
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

(1):当任务实例commod执行的时间小于延迟间隔时间delay情况


        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);

        System.out.println("当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("开始测试,当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("结束测试,当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }, 5, 5, TimeUnit.SECONDS); // 延迟5秒后执行,每隔3秒执行一次

执行结果为:

当前时间为:2024-03-18 15:15:06
开始测试,当前时间为:2024-03-18 15:15:11
结束测试,当前时间为:2024-03-18 15:15:14
 #第二次执行时间是第一次时间 + period 即11 + 5 = 16;
开始测试,当前时间为:2024-03-18 15:15:16
结束测试,当前时间为:2024-03-18 15:15:19

​ (2):当任务实例commod执行的时间大于间隔时间period情况

修改 TimeUnit.SECONDS.sleep(3); 为 TimeUnit.SECONDS.sleep(6);,执行查看运行结果!

执行结果为:

当前时间为:2024-03-18 15:19:57
开始测试,当前时间为:2024-03-18 15:20:02
结束测试,当前时间为:2024-03-18 15:20:08
开始测试,当前时间为:2024-03-18 15:20:09
结束测试,当前时间为:2024-03-18 15:20:15

总结
ScheduleAtFixedRate 每次执行时间为上一次任务开始起向后推一个时间间隔。分为两种情况:
(1)若command执行的时间小于period若每次执行时间为 :initialDelay, initialDelay+period, initialDelay+2period, …;

(2)若command执行的时间大于period,则command执行完,下一次任务将立即执行!下即下一次任务不会按照预期的时间间隔执行,每次执行时间为 :initialDelay, initialDelay+taskExecutorTIme, initialDelay+2*taskExecutorTIme, …;

taskExecutorTIme为任务执行的时间!

3.scheduleWithFixedDelay方法

该方法的作用是,当任务执行完毕后,让其延迟固定时间后再次运行(fixed-delay任务)。其中initialDelay表示提交任务后延迟多少时间开始执行任务command,delay表示当任务执行完毕后延长多少时间后再次运行command任务,unit是initialDelay和delay的时间单位。任务会一直重复运行直到任务中抛出了异常,被取消了,或者关闭了线程池。

参数:

  • command参数是任务实例,
  • initialDelay参数是初始换延迟时间,
  • delay参数是延迟间隔时间,
  • unit参数是时间单元
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)

(1):当任务实例commod执行的时间小于延迟间隔时间delay情况

 ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
        System.out.println("当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {

                System.out.println("开始测试,当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("结束测试,当前时间为:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
        }, 5, 3, TimeUnit.SECONDS); // 延迟5秒后执行,每隔3秒执行一次

执行结果:

当前时间为:2024-03-18 15:34:23
开始测试,当前时间为:2024-03-18 15:34:28
结束测试,当前时间为:2024-03-18 15:34:29
#第二次执行的时间 == 第一次任务开始时间+任务处理时间+delay延迟时间
#即 32 == 28 + 3秒 +  3秒 
开始测试,当前时间为:2024-03-18 15:34:32
结束测试,当前时间为:2024-03-18 15:34:33

(2):当任务实例commod执行的时间大于延迟间隔时间delay情况

修改 TimeUnit.SECONDS.sleep(3); 为 TimeUnit.SECONDS.sleep(6);,执行查看运行结果!

当前时间为:2024-03-18 15:38:28
开始测试,当前时间为:2024-03-18 15:38:33
结束测试,当前时间为:2024-03-18 15:38:39
#第二次任务执行开始时间 == 第一次任务执行开始时间 + 任务处理的时间 + delay延迟时间
#即 42 == 33 + 6 + 3
开始测试,当前时间为:2024-03-18 15:38:42
结束测试,当前时间为:2024-03-18 15:38:48

3:总结
不管任务command执行的时间是多长,下一次任务的执行时间都是上一次任务执行完后在等待延迟间隔delay时间后执行下一次任务。
ScheduleWithFixedDelay 每次执行时间为上一次任务结束起向后推一个时间间隔,即每次执行时间为:initialDelay, initialDelay+executeTime+delay, initialDelay+2executeTime+2delay

三、ScheduledExecutorService的创建方式

  public static void classCreate() {
        // 方式一
        ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(1);
        // 方式二,方式二和方式一可以等价
        ScheduledExecutorService scheduledExecutorService1 = Executors.newScheduledThreadPool(1);

    }

参考地址:

https://www.cnblogs.com/xuwc/p/14053613.html文章来源地址https://www.toymoban.com/news/detail-841218.html

到了这里,关于ScheduledThreadPoolExecutor 定时任务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 架构师系列- 定时任务(一)- 单机和分布式定时任务比较

    定时任务概述 在很多应用中我们都是需要执行一些定时任务的,比如定时发送短信,定时统计数据,在实际使用中我们使用什么定时任务框架来实现我们的业务,定时任务使用中会遇到哪些坑,如何最大化的提高定时任务的性能。 我们这里主要介绍单机和分布式两大类的解

    2024年04月27日
    浏览(36)
  • Java | 一分钟掌握定时任务 | 7 - ElasticJob分布式定时任务

    作者:Mars酱 声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我! ElasticJob 是面向互联网生态和海量任务的分布式调度解决方案。 它通过弹性调度、资源管控、以及任务治理的功能,打造一个适用于互联网场景的分

    2024年02月06日
    浏览(51)
  • Java | 一分钟掌握定时任务 | 9 - PowerJob分布式定时任务

    作者:Mars酱 声明:本文章由Mars酱整理编写,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我! 我们选择一套框架或者技术的时候,一定要知道它的特点和功能,不能为了(学习)技术而(选择)技术,那是对产品的不负责任。官方说有类似情况

    2024年01月24日
    浏览(52)
  • springboot 与异步任务,定时任务,邮件任务

    在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x之后,就已经内置了@Async来完美解决这个问题。 SpringBoot 实现比较简单 主启

    2024年02月10日
    浏览(39)
  • 11.定时任务&定时线程池详解

    3.1 新增定时任务池 11.定时任务定时线程池详解 ​ 当我们不用任务框架时,我们想自己写一个定时任务时,我们能想起那个工具类呢?Timer ?还有吗?不知道了,下面我们要讲下ScheduledThreadPoolExecutor,定时任务线程池,可以执行一次任务,还可以执行周期性任务。 1.0 Schedu

    2023年04月08日
    浏览(37)
  • js------定时任务和延时任务

    取消定时任务  取消定时任务,有的时候需要将定时器定义成全局,这样就可以在别的函数或者用户点击别的按钮取消定时任务 setTimeout()      延时任务 取消延时任务

    2024年02月15日
    浏览(45)
  • 使用shedlock实现分布式定时任务锁【防止task定时任务重复执行】

    第一步:引入shedlock相关依赖 ShedLock还可以使用Mongo,Redis,Hazelcast,ZooKeeper等外部存储进行协调,例如使用redis则引入下面的包 第二步:创建数据库表结构,数据库表的脚本如下: 第三步:添加shedlock配置类 (定时任务防重复执行的配置类) 第四步:在启动类上添加启动注

    2024年02月10日
    浏览(41)
  • 【运维】Linux定时任务 定时执行脚本

    五分钟执行一次sh脚本 进入编辑页面 crontab -e 按Insert   进行编辑  # 每两分钟执行一次 */2 * * * * /usr/local/start.sh 依次按 :wq 进行保存  即时生效 重启 #设定crond服务为开机自启动 接下来,在介绍 crontab 命令。该命令和 at 命令类似,也是通过 /etc/cron.allow 和 /etc/cron.deny 文件来限

    2024年02月10日
    浏览(49)
  • 复习之系统定时任务及延迟任务

    at  +时间 :具体时间设定延迟任务 设定成功后“ ctrl + d \\\"发起任务,\\\" ctrl + c \\\" 取消。 at  -l  :查看延迟任务 at  -c  1 :查看序号为1 的延迟任务的内容 at  -r  1 :取消序号为1 的延迟任务 at  now+1min : 设定1分钟后的延迟任务 ------------------------------------------------------实验-

    2024年02月16日
    浏览(40)
  • Java定时任务、自动化任务调度

    Java提供了多种方式来实现定时任务,使得开发人员能够在指定的时间间隔或固定时间点执行特定的任务。本文将介绍Java中实现定时任务的几种常用方法,并探讨它们的优势和适用场景。 Java中的Timer类是最早引入的定时任务工具,它可以用于执行一次性或重复性的定时任务。

    2024年02月16日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包