有个Redis安装使用教程,可视化界面,有需要的话,可以打开这个链接去看一下
https://blog.csdn.net/weixin_45507672/article/details/105973279
创建个maven项目,在pom.xml文件加上以下依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
以下是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<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
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序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
// hash的value序列化方式采用jackson
template.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;
@Autowired
private RedisTemplate<String,String> 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;
}
@Override
public 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注解
然后就可以启动运行,从控制台可以看到三个相同的定时任务在时间段内是交换执行的。