Java定时任务

一、java.util.Timer

java.util.Timer 类允许您在未来的某个时间执行一个任务,或者在一定的时间间隔执行任务。您可以创建一个 Timer 实例,并调用其 schedule() 方法来安排任务的执行。这种方式比较简单,但在高并发环境下可能不够灵活。

1.代码实现

Timer timer = new Timer();
 //延迟1s,每个2s打印一次
 timer.schedule(new TimerTask() {
     @Override
     public void run() {
         System.out.println("111111111111");
     }
 }, 1000,2000);

2.常用方法

Timer 常用方法

二、java.util.concurrent.Executors

Java 提供了 ExecutorService 和 ScheduledExecutorService 接口,以及一些工厂方法来创建线程池和调度执行任务。ScheduledExecutorService 可以用于执行延迟任务或周期性任务。

1.代码实现

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleAtFixedRate(()->{
    System.out.println("1111111");
},1,2, TimeUnit.SECONDS);

2.常用方法

在这里插入图片描述

三、Spring Framework 定时任务

1.启用定时任务功能:

在配置类上添加 @EnableScheduling 注解,以启用 Spring 的定时任务功能。

@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

2.创建定时任务方法:

在 Spring 管理的 Bean 类中定义一个方法,并使用 @Scheduled 注解标记该方法作为定时任务。可以指定定时任务的触发时间、频率等。

@RestController
public class ScheduledTasksController {

    @Scheduled(cron = "0 30 9 * * ?")//每天九点半执行
    public void task1(){
        System.out.println("111111111");
    }

    @Scheduled(fixedRate = 5000)//每个5s执行
    public void task2(){
        System.out.println("222222222");
    }
}

3.cron表达式

每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天22点执行一次:0 0 22 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
每月最后一天21点执行一次:0 0 21 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L
在12分、13分、14分执行一次:0 12,13,14 * * * ?
每天的0点、3点、5点、7点都执行一次:0 0 0, 3,5,7 * * ?
Java检测cron表达式
先引入quartz的jar包

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.2</version>
</dependency>

检测代码

boolean validExpression = CronExpression.isValidExpression(cron);
if (validExpression) {
    //cron验证通过
} else {
    //cron颜值失败
}

四、动态配置定时时间

1.通过yml配置:

问题: 每次修改时间都需要重新启动服务;

@Component
@Slf4j
public class DynamicScheduledTaskRegistrar {
    @Resource
    private TaskScheduler taskScheduler;
    @Value("${schedule.cron}")
    private String cronExpression;

    @PostConstruct
    public void init() {
        scheduleTask();
    }

    private void scheduleTask() {
        Runnable task = () -> {
            //业务逻辑
        };
        Trigger trigger = new CronTrigger(cronExpression);
        taskScheduler.schedule(task, trigger);
    }
}

2.通过set动态配置

方式一
@Component
@Slf4j
public class DynamicScheduledTaskRegistrar {
    @Resource
    private TaskScheduler taskScheduler;

    private ScheduledFuture<?> scheduledFuture;
    private String cronExpression = "*/10 * * * * *"; // 默认的cron表达式

    @PostConstruct
    public void init() {
        scheduleTask();
    }

    private void scheduleTask() {
        Runnable task = () -> {
            // 这里写你的定时任务逻辑
            System.out.println("执行定时任务");
        };

        Trigger trigger = new CronTrigger(cronExpression);
        scheduledFuture = taskScheduler.schedule(task, trigger);
    }

    public void setCronExpression(String newCronExpression) {
        this.cronExpression = newCronExpression;

        // 取消之前的定时任务并重新调度
        if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
            scheduledFuture.cancel(true);
        }
        scheduleTask();
    }
}
方式二

1.首先配置taskScheduler

@Configuration
@EnableScheduling
public class SchedulingConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10); // 设置线程池大小
        scheduler.setThreadNamePrefix("ScheduledTask-");
        scheduler.initialize();
        return scheduler;
    }
}

2.实现SchedulingConfigurer

@Component
@Slf4j
public class DynamicScheduledTask implements SchedulingConfigurer {
    private String cronExpression = ""; //cron 表达式
    private ScheduledFuture<?> scheduledFuture;

    private final TaskScheduler taskScheduler;

    public DynamicScheduledTask(TaskScheduler taskScheduler) {
        this.taskScheduler = taskScheduler;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        scheduledFuture = taskScheduler.schedule(this::executeTask, new CronTrigger(cronExpression));
    }

    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
        // 根据新的 cron 表达式重新调度任务
        scheduledFuture.cancel(false);
        scheduledFuture = taskScheduler.schedule(this::executeTask, new CronTrigger(cronExpression));
    }

    public void executeTask() {
        // 定时任务执行的操作
        System.out.println("执行定时任务");
    }
}

不足之处望海涵

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/554283.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git学习与码云实战

Git学习与码云实战 Git安装 概述&#xff1a; Git 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速的处理从很小到非常大的项目版本管理&#xff0c;是目前使用范围最广的版本管理工具。 下载安装&#xff1a; 下载地址&#xff1a;https://git-scm.com/ 下载后傻瓜…

李彦宏:开源模型会越来越落后

李彦宏&#xff1a;开源模型会越来越落后 昨天听完的李总讲座 大家以前用开源觉得开源便宜&#xff0c;其实在大模型场景下&#xff0c;开源是最贵的。所以&#xff0c;开源模型会越来越落后。 ——李彦宏 至于开源还是闭源&#xff0c;这和企业的利益息息相关。 随着科技的迅猛…

双向链表详解

一.双向链表结构 我们一般所说的双向链表是带头循环双向链表&#xff0c;这里的带头更我们之前的头节点不是一回事。带头链表里的头节点&#xff0c;实际上为哨兵位&#xff0c;哨兵位的头节点种是不存放任何有效数据的&#xff0c;只是站在这里起到放哨的作用。 哨兵位的意义…

【C++从练气到飞升】08---模板

&#x1f388;个人主页&#xff1a;库库的里昂 ✨收录专栏&#xff1a;C从练气到飞升 &#x1f389;鸟欲高飞先振翅&#xff0c;人求上进先读书。 目录 一、泛型编程 什么是泛型编程: 二、函数模板 1. 函数模板概念 2. 函数模板格式 3. 函数模板的原理 4. 函数模板的实例…

Nginx part2.2

目录 如何用Nginx搭建多网址服务器&#xff1f; 基于ip地址的虚拟主机 1. 先建立存储网页的目录 2.进行子配置 3.编写.conf文件 基于端口号的虚拟主机 基于域名的虚拟主机 如何用Nginx搭建多网址服务器&#xff1f; 有些网站&#xff0c;ip不同&#xff0c;域名不同&…

格林兰岛和南极洲的流域边界文件下载

&#xff08;1&#xff09;南极流域系统边界和掩蔽区 下图显示了由戈达德冰面高程小组使用ICESat数据开发的南极分水岭。我们对西南极冰盖&#xff08;系统18-23和1&#xff09;、东南极冰盖&#xff08;系统2-17&#xff09;和南极半岛&#xff08;系统24-27&#xff09;的定…

案例与脚本实践:DolphinDB 轻量级实时数仓的构建与应用

DolphinDB 高性能分布式时序数据库&#xff0c;具有分布式计算、事务支持、多模存储、以及流批一体等能力&#xff0c;非常适合作为一款理想的轻量级大数据平台&#xff0c;轻松搭建一站式的高性能实时数据仓库。 本教程将以案例与脚本的方式&#xff0c;介绍如何通过 Dolphin…

LevelDB源码阅读笔记(1、整体架构)

LevelDB源码阅读笔记&#xff08;1、整体架构&#xff09; LeveDB源码笔记系列&#xff1a; LevelDB源码阅读笔记&#xff08;0、下载编译leveldb&#xff09; LevelDB源码阅读笔记&#xff08;1、整体架构&#xff09; 前言 对LevelDB源码的博客&#xff0c;我准备采用总…

ragflow知识库使用案例

参考: https://github.com/infiniflow/ragflow/blob/main/README_zh.md 支持丰富的文件类型,包括 Word 文档、PPT、excel 表格、txt 文件、图片、PDF、影印件、复印件、结构化数据, 网页等。 运行步骤: 1、确保 vm.max_map_count 不小于 262144 【更多】: 如需确认 vm.…

【大数据】分布式文件系统HDFS

目录 1.什么是分布式文件系统 2.HDFS的特点 3.HDFS的核心概念 4.HDFS的体系结构 5.HDFS的配置建议 6.HDFS的局限性 7.HDFS的存储机制 7.1.数据冗余机制 7.2.错误与恢复 8.HDFS数据读写过程 1.什么是分布式文件系统 分布式文件系统是整个大数据技术的基础&#xff0c…

单位个人信息宣传这样投稿审核轻松出稿快

在我担任单位信息宣传员的初期阶段,每月的对外信息宣传任务就像一座大山横亘在前,尤其是与媒体对接、投稿发表的工作,更是充满了挑战与艰辛。那段时光,我如同一个摸索前行的独行者,在浩瀚的媒体海洋中“摸着石头过河”。 我曾经花费大量的时间逐一查找各类媒体联系方式,通过电话…

短视频去水印解析接口 可测试

短视频解析聚合接口80多个热们短视频平台。可测试 接口开发文档&#xff1a; 返回格式&#xff1a; JSON 请求方式&#xff1a; GET/POST 示例请求地址&#xff1a;https://www.dspqsy.vip/spapi?keykey&url短视频url 请求参数说明&#xff1a; 字段必填类型说明url是…

良友:献上今天(打开心窗说亮话)- 情绪的秘密

目录 一 二 三 四 五 六 七 八 九 十 十一 十二 十三

C/C++中程序内存区域划分

总结C/C中程序内存区域划分 C/C程序内存分配的几个区域&#xff1a; 1. 栈区&#xff08;stack&#xff09;&#xff1a;在执⾏函数时&#xff0c;函数内局部变量的存储单元都可以在栈上创建&#xff0c;函数执⾏结束时 这些存储单元⾃动被释放。栈内存分配运算内置于处理器的…

【Vue3】StoresTorefs:简化状态管理的实用工具

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

淘宝京东商品详情API接口:打造高效电商数据交互新体验

淘宝京东商品详情API接口&#xff1a;打造高效电商数据交互新体验 随着电商行业的迅猛发展&#xff0c;商家们对于商品详情数据的获取和更新需求日益增长。为满足这一需求&#xff0c;淘宝和京东两大电商巨头纷纷推出了商品详情API接口&#xff0c;为商家提供了高效、便捷的数…

uni-app 小兔鲜儿 Day 6(有作业)

​ 黑马程序员uni-app 小兔鲜儿 项目及bug记录&#xff08;下&#xff09; Day 6&#xff08;有作业&#xff09; 包含视频中提到的作业及最终琐屑代码 Day 6 填写订单页面 相关琐屑代码 <script setup lang"ts"> import { computed, ref } from vue impo…

玩转OurBMC第六期:OpenBMC之传感器配置及使用

栏目介绍&#xff1a;“玩转OurBMC”是OurBMC社区开创的知识分享类栏目&#xff0c;主要聚焦于社区和BMC全栈技术相关基础知识的分享&#xff0c;全方位涵盖了从理论原理到实践操作的知识传递。OurBMC社区将通过 “玩转OurBMC” 栏目&#xff0c;帮助开发者们深入了解到社区文化…

光纤和铜缆:了解不同通信媒介的优势

在现代通信技术中&#xff0c;光纤和铜缆是两种主要的数据传输媒介。它们各有优势和局限性&#xff0c;但都在我们的日常生活中扮演着不可或缺的角色。 左侧&#xff08;网络跳线&#xff09;右侧&#xff08;光纤跳线&#xff09; 一、光纤的原理与优势 ADOP光纤跳线 光纤通信…

LeetCode 1.两数之和(HashMap.containsKey()、.get、.put操作)

给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…
最新文章