有个Redis安装使用教程,可视化界面,有需要的话,可以打开这个链接去看一下
https://blog.csdn.net/weixin_45507672/article/details/105973279
创建个maven项目,在pom.xml文件加上以下依赖
org.springframework.boot spring-boot-starter-data-redis org.springframework.boot spring-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注解
然后就可以启动运行,从控制台可以看到三个相同的定时任务在时间段内是交换执行的。