ScheduledExecutorService 实现定时任务「建议收藏」

ScheduledExecutorService 实现定时任务「建议收藏」ScheduledExecutorService实现定时任务一、背景二、ScheduledExecutorService(java.util.concurrent并发包引进)附:代码1.Main.java2.TaskService.java3.application.ymlGitHub:link. 欢迎star一、背景项目升级版本之后,新加了一些需求,其中有一个需要每天定时清理数据的业务逻辑。第一时间想到的实现方法是while循环里做sleep,想想好像有点low,就特此了解了一些Java实现定

大家好,又见面了,我是你们的朋友全栈君。


GitHub:
link. 欢迎star

一、背景

  • 项目升级版本之后,新加了一些需求,其中有一个需要每天定时清理数据的业务逻辑。第一时间想到的实现方法是while循环里做sleep,想想好像有点low,就特此了解了一些Java实现定时任务的方式。大概有以下三种实现方式:
  1. JDK自带的定时器实现 :Timer类和JDK1.5+ 新增的定时任务接口ScheduledExecutorService。
  2. Quartz :Java编写的开源作业调度框架。
  3. Spring3.0以后自带的task :据了解可以将它看成一个轻量级的Quartz。

二、ScheduledExecutorService(java.util.concurrent并发包引进)

  1. 创建线程池,通过线程池的方式来执行任务。
    // private ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
    
  2. 第一次执行任务的延时时间(initialDelay),周期执行的时间间隔(period)。在这里插入图片描述
  • scheduleAtFixedRate:延时设定时间(initialDelay)后执行第一次任务,每隔时间间隔(period)再次执行任务。
  • schedule:延时设定时间(initialDelay)后只执行一次任务。
  • scheduleWithFixedDelay:延时设定时间(initialDelay)后执行第一次任务,随后每次任务执行完后延迟设定时间(delay)再次执行任务。

附:代码

1.Main.java

@Slf4j
@Component
public class Main implements ApplicationRunner { 
   

    public static final ThreadLocal<SimpleDateFormat> FORMAT = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    public static final ThreadLocal<SimpleDateFormat> FORMAT_DAY = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
    private ScheduledExecutorService scheduledExecutorService; //定时任务线程池

    @Value("${task.time_clear_sector}")
    private String time_clear_sector; //任务执行时间
    @Resource
    private TaskService taskService; //定时任务

    @PostConstruct
    public void init() { 
   
        // 创建线程池
        // scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService = Executors.newScheduledThreadPool(10);
    }

    @Override
    public void run(ApplicationArguments args) { 
   
        for (int i = 0; i < 10; i++) { 
   
            System.out.println("Run!!");
        }

        long initialDelay = 12 * 60 * 60L; //定时任务延时启动
        long period = 24 * 60 * 60L; //定时任务时间间隔

        // 项目启动后,计算定时任务延时的启动时间
        long currentTimeMillis = System.currentTimeMillis();
        String taskTime = FORMAT_DAY.get().format(currentTimeMillis) + " " + time_clear_sector;
        try { 
   
            long taskTimestamp = FORMAT.get().parse(taskTime).getTime();
            initialDelay = (taskTimestamp - currentTimeMillis) > 0 ? (taskTimestamp - currentTimeMillis) / 1000 : 1;
        } catch (ParseException e) { 
   
            e.printStackTrace();
        }

        // 定时任务启动(延时时间后周期执行)
        scheduledExecutorService.scheduleAtFixedRate(taskService, initialDelay, period, TimeUnit.SECONDS);
    }
}

2.TaskService.java

@Slf4j
@Service
public class TaskService implements Runnable { 
   

    @Override
    public void run() { 
   
        // 定时任务业务逻辑
        log.info("taskService run!!");
    }
}

3.application.yml

#server:
# port: 9116

spring:
  main:
    web-application-type: none

task:
  time_clear_sector: "18:00:00"

GitHub: link. 欢迎star

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/137106.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月2日 下午4:00
下一篇 2022年6月2日 下午4:16


相关推荐

  • c++构造函数是否可以抛出异常_什么叫抛出异常

    c++构造函数是否可以抛出异常_什么叫抛出异常从语法上来说,构造函数和析构函数都可以抛出异常。但从逻辑上和风险控制上,构造函数和析构函数中尽量不要抛出异常,万不得已,一定要注意防止资源泄露。1.构造函数中抛出异常在C++构造函数中,既需要分配内存,又需要抛出异常时要特别注意防止内存泄露的情况发生。因为在构造函数中抛出异常,在概念上将被视为该对象没有被成功构造,因此当前对象的析构函数就不会被调用。同时,由于构造函数本身也是一个函数,在函数体内抛出

    2022年8月12日
    10
  • OpenClaw + Discord 完整配置指南:Guild、Channel、Session、Heartbeat 到底怎么对应

    OpenClaw + Discord 完整配置指南:Guild、Channel、Session、Heartbeat 到底怎么对应

    2026年3月13日
    2
  • Java学习之集合篇

    Java学习之集合篇0x00前言上篇文章的常用类,其实就已经讲到了,这个ArrayList集合,但是ArrayList只是集合中的其中一种,那这篇文章就来讲讲关于集合的一些对象。0x01集合

    2021年12月12日
    56
  • 常用dos命令(八)–COPY命令

    常用dos命令(八)–COPY命令今天的是copy(复制)命令,说起这个命令,也许你没使用过这个命令,但是平常生活与工作中总会长期用到ctrl+c和ctrl+v这两个功能吧。下面是几个小例子:1、将桌面的hello.txt文件复制到d盘:c:\Users\DT236\Desktop>copyhello.txtd:2、将多个文件合并在一个文件里面:c:\Users\DT236\Desktop>copyh

    2022年7月18日
    25
  • UE4制作星际天空球[通俗易懂]

    UE4制作星际天空球[通俗易懂]效果图:需要的东东西:6张无缝连接的图片,如果没有的推荐大家下载“Spacescape”3dsMax2018软件EpicGamesLauncher(UE4游戏引擎)然后就是阅读本博客了教程开始首先教大家使用Spacescape如果有素材的读者可以直接跳过打开界面如下点击左上角文件打开或者直接快捷键Ctro+O选择素材笔者推荐最后两个,不过无妨大家都

    2026年4月16日
    2
  • openjdk使用_深入地理解

    openjdk使用_深入地理解目录前言一、从JDK源码看双亲委派二、使用步骤1.引入库2.读入数据总结前言关于JVM类加载的基础理论知识,请参照《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(上)和《深入理解Java虚拟机》读书笔记(六)–虚拟机类加载机制(下)。一、从JDK源码看双亲委派注:博主是使用的是openjdk8,换了新电脑还没有去编译源码,所以看的是静态代码,关于如何编译和调试源码,网上不少文章都有介绍,这里就不赘述了我们都知道在Java类加载中,除了BootStrap加载器,App和Ext加载

    2022年8月11日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号