@Scheduled定时任务搭配Redis防止多实例定时重复调用
创始人
2024-03-25 13:41:42
0

有个Redis安装使用教程,可视化界面,有需要的话,可以打开这个链接去看一下

https://blog.csdn.net/weixin_45507672/article/details/105973279

创建个maven项目,在pom.xml文件加上以下依赖

org.springframework.bootspring-boot-starter-data-redis

org.springframework.bootspring-boot-starter-web

以下是Redis的配置文件 

## redis所在的服务器IP
spring.redis.host=127.0.0.1
## 端口
spring.redis.port=6379
## 密码,我这里没有设置,所以不填
spring.redis.password=
## 设置最大连接数,0为无限
spring.redis.pool.max-active=8
## 选择哪个Redis库,可忽略,默认是0
spring.redis.database=1

 

接着然后是创建Redis配置类

package com.example.schedulingtasks.config;import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Bean@SuppressWarnings("all")public RedisTemplate redisTemplate(RedisConnectionFactory factory) {RedisTemplate template = new RedisTemplate();template.setConnectionFactory(factory);Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);ObjectMapper om = new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}}

接着创建一个定时任务Bean

/** Copyright 2012-2015 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**	  https://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/package com.example.schedulingtasks;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;import net.javacrumbs.shedlock.spring.annotation.SchedulerLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;@Component
public class ScheduledTasks {private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");private static int setnx=0;@Autowiredprivate RedisTemplate redisTemplate;ExecutorService executorService = Executors.newCachedThreadPool();@Scheduled(cron = "0/20 * * * * ?")public void reportCurrentTimeOne() throws InterruptedException {
//		log.info("进来方法1了 {}", dateFormat.format(new Date()));Boolean status1 = redisTemplate.opsForValue().setIfAbsent("status", "1");if (status1){String status111 = redisTemplate.opsForValue().get("status");log.info("The time1 is do {},{}", dateFormat.format(new Date()),status111);for (int i = 0; i < 10000; i++) {redisTemplate.opsForValue().get("a");}} else {String status = redisTemplate.opsForValue().get("status");if (status.equals("3")){log.info("(方法1)有其它定时器已经在执行 {}",dateFormat.format(new Date()));}else {Boolean status11 = redisTemplate.delete("status");log.info("方法1:delete{}",status11);log.info("(方法1)有其它定时器已经在执行 {}",dateFormat.format(new Date()));}}}@Scheduled(cron = "0/20 * * * * ?")public void reportCurrentTimeTwo() throws InterruptedException {
//		log.info("进来方法2了 {}", dateFormat.format(new Date()));Boolean status2 = redisTemplate.opsForValue().setIfAbsent("status", "2");if (status2) {String status222 = redisTemplate.opsForValue().get("status");log.info("The time2 is do {},{}", dateFormat.format(new Date()),status222);for (int i = 0; i < 10000; i++) {redisTemplate.opsForValue().get("a");}} else {String status = redisTemplate.opsForValue().get("status");if (status.equals("1")){log.info("(方法2)有其它定时器已经在执行 {}",dateFormat.format(new Date()));}else {Boolean status22 = redisTemplate.delete("status");log.info("方法2:delete{}",status22);log.info("(方法2)有其它定时器已经在执行 {}",dateFormat.format(new Date()));}}}@Scheduled(cron = "0/20 * * * * ?")public void reportCurrentTimeThree() throws InterruptedException {
//		log.info("进来方法2了 {}", dateFormat.format(new Date()));Boolean status3 = redisTemplate.opsForValue().setIfAbsent("status", "3");if (status3) {String status333 = redisTemplate.opsForValue().get("status");log.info("The time3 is do {},{}", dateFormat.format(new Date()),status333);for (int i = 0; i < 10000; i++) {redisTemplate.opsForValue().get("a");}} else {String status = redisTemplate.opsForValue().get("status");if (status.equals("2")){log.info("(方法3)有其它定时器已经在执行 {}",dateFormat.format(new Date()));}else{Boolean status33 = redisTemplate.delete("status");log.info("方法3:delete{}",status33);log.info("(方法3)有其它定时器已经在执行 {}",dateFormat.format(new Date()));}}}//个人觉得在多线程下,fixedRate和fixedDelay是没有啥区别的
//	@Scheduled(fixedDelay = 5000)
//	public void runfixedDelay() {
//		System.out.println("fixedDelay定时任务开始了---------------------"+new Date());
//		for (int i = 0; i <= 10; i++) {
//			executorService.execute(new SubThread(i));
//		}
//	}//	@Scheduled(fixedRate = 5000)
//	public void runfixedRate() {
//		System.out.println("fixedRate定时任务开始了---------------------"+new Date());
//		for (int i = 0; i <= 10; i++) {
//			executorService.execute(new SubThread(i));
//		}
//	}//	@Scheduled(fixedRate = 5000)
//	public void runfixedRatesingle() throws InterruptedException {
//		//加入逻辑执行时间超过定时器设定时间,那么会在逻辑执行完毕后的第一时间继续调用
//		//也就是第一次执行时间是12:00:04  逻辑执行需要8秒,就是12:00:12执行完成
//		//那么下一次定时器执行方法的时间就是12:00:12
//		System.out.println("runfixedRatesingle定时任务开始了---------------------" + new Date());
//		Thread.sleep(6*1000);
//		System.out.println("执行完毕" + new Date());
//	}//	@Scheduled(fixedDelay = 5000)
//	public void runfixedDelaysingle() throws InterruptedException {
//		//加入逻辑执行时间超过定时器设定时间,那么会在逻辑执行完毕后需要等待定时器设定的时间后继续调用
//		//也就是第一次执行时间是12:00:04  逻辑执行需要8秒,就是12:00:12执行完成
//		//那么下一次定时器执行方法的时间就是12:00:20
//		System.out.println("runfixedDelayingle定时任务开始了---------------------" + new Date());
//		Thread.sleep(8*1000);
//		System.out.println("执行完毕" + new Date());
//	}class SubThread extends Thread{private final int i;public SubThread(int i){this.i=i;}@Overridepublic void run() {try {//要是执行方法的时间不够,定时任务就算启动了,也要等上一个任务执行完毕后才会执行Thread.sleep(8000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("线程名称"+Thread.currentThread().getName()+"当前的任务"+i+new Date());}}//“30 * * * * ?” 每半分钟触发任务
//“30 10 * * * ?” 每小时的10分30秒触发任务
//“30 10 1 * * ?” 每天1点10分30秒触发任务
//“30 10 1 20 * ?” 每月20号1点10分30秒触发任务
//“30 10 1 20 10 ? *” 每年10月20号1点10分30秒触发任务
//“30 10 1 20 10 ? 2011” 2011年10月20号1点10分30秒触发任务
//“30 10 1 ? 10 * 2011” 2011年10月每天1点10分30秒触发任务
//“30 10 1 ? 10 SUN 2011” 2011年10月每周日1点10分30秒触发任务
//“15,30,45 * * * * ?” 每15秒,30秒,45秒时触发任务
//“15-45 * * * * ?” 15到45秒内,每秒都触发任务
//“15/5 * * * * ?” 每分钟的每15秒开始触发,每隔5秒触发一次
//“15-30/5 * * * * ?” 每分钟的15秒到30秒之间开始触发,每隔5秒触发一次
//“0 0/3 * * * ?” 每小时的第0分0秒开始,每三分钟触发一次
//“0 15 10 ? * MON-FRI” 星期一到星期五的10点15分0秒触发任务
//“0 15 10 L * ?” 每个月最后一天的10点15分0秒触发任务
//“0 15 10 LW * ?” 每个月最后一个工作日的10点15分0秒触发任务
//“0 15 10 ? * 5L” 每个月最后一个星期四的10点15分0秒触发任务
//“0 15 10 ? * 5#3” 每个月第三周的星期四的10点15分0秒触发任务//	Timer
//	ExecutorService
//	Spring @Scheduled
//  quartz
//	xxljob
//  elastic-job
}

 最后在启动类上加上@EnableScheduling注解

 然后就可以启动运行,从控制台可以看到三个相同的定时任务在时间段内是交换执行的。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...