当前位置: 首页 > news >正文

六种定时任务记录

1、java自带的Timer

Timer是java中自带的类。
优点:使用简单,缺点是当添加并执行多个任务时,前面任务的执行用时和异常将影响到后面任务。

Timer timer = new Timer();timer.schedule(new TimerTask() {int i = 0;@Overridepublic void run() {System.out.println("循环执行的代码块"+ i++);}},启动后多长时间按第一次开始执行,间隔执行时间);

讲解:源码讲解

2、ScheduledThreadPool-定时任务线程池

ScheduledExecutorService 也是Java自带的类,它可以实现Timer具备的所有功能,并解决了 Timer类存在的问题。
优点:该类是JDK1.5自带的类,使用简单,缺点是该方案仅适用于单机环境。

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(该线程池里的线程数);scheduledThreadPool.scheduleAtFixedRate(new Runnable() { public void run() {System.out.println("循环代码块");}},初始延迟,迟期, 时间单位);
参数:1、任务主体(循环代码块) 
2、首次执行的延时时间
3、任务执行间隔 
4、间隔时间单位

讲解:源码讲解

3、Spring Task

Spring系列框架中Spring Framework自带的定时任务,可以实现某些特定需求,比如每周一执行某任务。
1、开启定时任务在SpringBoot的启动类上声明 @EnableScheduling

@SpringBootApplication
@EnableScheduling //开启定时任务
public class SystemApplication {  // --  -- 
}

2、添加定时任务;只需使用@Scheduled注解标注即可,如果有多个定时任务,可以创建多个@Scheduled标注的方法。Spring Boot 启动后会自动加载并执行定时任务,无需手动操作。

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component  // 把此类托管给 Spring
public class TaskUtils {    // 添加定时任务    @Scheduled(cron = "30 00 10 0 0 5") // cron表达式:每周一 10:00:30 执行    public void doTask(){        System.out.println("我是定时任务~");    }
}

4、分布式定时任务

分布式环境可以使用 Redis 来实现定时任务。
使用 Redis 实现延迟任务的方法大体可分为两类:通过 ZSet 的方式和键空间通知的方式。

ZSet 实现方式

通过 ZSet 实现定时任务的思路是,将定时任务存放到 ZSet 集合中,并且将过期时间存储到 ZSet 的 Score 字段中,然后通过一个无线循环来判断当前时间内是否有需要执行的定时任务,如果有则进行执行。

import redis.clients.jedis.Jedis;
import utils.JedisUtils;
import java.time.Instant;
import java.util.Set;
public class DelayQueueExample {        private static final String _KEY = "DelayQueueExample";        public static void main(String[] args) throws InterruptedException {        Jedis jedis = JedisUtils.getJedis();        // 30s 后执行        long delayTime = Instant.now().plusSeconds(30).getEpochSecond();       jedis.zadd(_KEY, delayTime, "order_1");        // 继续添加测试数据        jedis.zadd(_KEY, Instant.now().plusSeconds(2).getEpochSecond(), "order_2");       jedis.zadd(_KEY, Instant.now().plusSeconds(2).getEpochSecond(), "order_3");        jedis.zadd(_KEY, Instant.now().plusSeconds(7).getEpochSecond(), "order_4");        jedis.zadd(_KEY, Instant.now().plusSeconds(10).getEpochSecond(), "order_5");        // 开启定时任务队列        doDelayQueue(jedis);    }    /**     * 定时任务队列消费     * @param jedis Redis 客户端     */    public static void doDelayQueue(Jedis jedis) throws InterruptedException {        while (true) {            // 当前时间            Instant nowInstant = Instant.now();            long lastSecond = nowInstant.plusSeconds(-1).getEpochSecond(); // 上一秒时间            long nowSecond = nowInstant.getEpochSecond();            // 查询当前时间的所有任务            Set data = jedis.zrangeByScore(_KEY, lastSecond, nowSecond);            for (String item : data) {                // 消费任务                System.out.println("消费:" + item);            }            // 删除已经执行的任务            jedis.zremrangeByScore(_KEY, lastSecond, nowSecond);            Thread.sleep(1000); // 每秒查询一次        }    }
}

键空间通知

可以通过 Redis 的键空间通知来实现定时任务,它的实现思路是给所有的定时任务设置一个过期时间,等到了过期之后,我们通过订阅过期消息就能感知到定时任务需要被执行了,此时我们执行定时任务即可。
默认情况下 Redis 是不开启键空间通知的,需要我们通过 config set notify-keyspace-events Ex 的命令手动开启。

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;
import utils.JedisUtils;
public class TaskExample {    public static final String _TOPIC = "__keyevent@0__:expired"; // 订阅频道名称   public static void main(String[] args) {       Jedis jedis = JedisUtils.getJedis();       // 执行定时任务        doTask(jedis);    }   /**     * 订阅过期消息,执行定时任务     * @param jedis Redis 客户端     */    public static void doTask(Jedis jedis) {        // 订阅过期消息        jedis.psubscribe(new JedisPubSub() {            @Override            public void onPMessage(String pattern, String channel, String message) {                // 接收到消息,执行定时任务                System.out.println("收到消息:" + message);            }            }, _TOPIC);    }
}

SpringBoot中使用Redis实现分布式锁

5、springboot整合xxl-job实现定时任务

注:后续继续补充

http://www.lryc.cn/news/461327.html

相关文章:

  • Dos下编译环境搭建和C运行程序生成
  • 【MySQL】入门篇—SQL基础:数据查询语言(DQL):复杂的SELECT语句
  • Appium环境搭建、Appium连接真机
  • 【X线源】关于滨松MCS2软件的说明
  • 【深度学习代码调试2】环境配置篇(中) -- 列出conda环境中所有env的pytorch版本
  • C语言运算符和表达式
  • RetinaNet 分类头和回归头的网络结构分析
  • app测试有哪些内容?广东深圳软件测试机构推荐
  • 新乡医学院第一附属医院启动巨额医疗设备整体维保招标
  • Linux——综合实用操作
  • 一个Idea:爆改 T480
  • 网络编程(21)——通过beast库快速实现http服务器
  • Logback
  • Sub - Adjacent Transformer — 对AT的有趣改进
  • 『Mysql集群』Mysql高可用集群之主从复制 (一)
  • PHP获取图片属性(size, width, 和 height)的函数
  • MySQL启动失败解决方案
  • Spring Boot中使用MyBatis-Plus和MyBatis拦截器来实现对带有特定注解的字段进行AES加密。
  • Python GUI 编程:tkinter 初学者入门指南——框架、标签框架
  • Mac 远程 Windows 等桌面操作系统工具 Microsoft Remote Desktop for Mac 下载安装详细使用教程
  • 初级网络工程师之从入门到入狱(四)
  • MinIO配置与使用
  • 【漏洞复现】SpringBlade menu/list SQL注入漏洞
  • 物联网智能项目(含案例说明)
  • 【YOLOv8改进】 YOLOv8 更换骨干网络之GhostNetV3步骤详解
  • 成绩查询小程序,家长查分超方便~
  • 鸿蒙开发(NEXT/API 12)【上传下载文件】远场通信场景
  • 快速理解AUTOSAR CP的软件架构层次以及各层的作用
  • 【Unity】Unity中接入Admob聚合广告平台,可通过中介接入 AppLovin,Unity Ads,Meta等渠道的广告
  • PythonExcel批量pingIP地址