一、概述
Spring Scheduler是Spring提供的一个任务调度框架,它是基于org.springframework.scheduling.TaskScheduler接口实现的。它目前有四个实现类,但我们常用的是org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler。另外还有一个重要的接口org.springframework.scheduling.Trigger,这个接口是触发器,也就是我们用来定义任务执行时间的。Spring Scheduler的本质其实就是申明了一个线程池,然后定时异步的调用我们的任务。
二、缓存预热的意义
在新增少,总数据量多的情况下,能够让用户体验感更好,更够很快的查询到数据
三、demo实现
Springboot中自动整合了,不需要引入依赖
1).在启动类中添加注解@EnableScheduling
/**
* 启动类
*/
@SpringBootApplication
@MapperScan("com.sgx.mapper")
@EnableScheduling
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
2).定时任务
这个注解代表会定时执行,但是什么时候执行呢,需要cron表达式来证明
在线cron表达式生成:
@Scheduled(cron = "0 31 0 * * *")
/**
* 缓存预热任务
*/
@Component
@Slf4j
public class PreCacheJob {
@Resource
private UserService userService;
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Resource
private RedissonClient redissonClient;
// 每天执行,
@Scheduled(cron = "0 31 0 * * *")
public void doCacheRecommendUser() {
RLock lock = redissonClient.getLock("yupao:precachejob:docache:lock");
try {
// 只有一个线程能获取到锁
if (lock.tryLock(0, -1, TimeUnit.MILLISECONDS)) {
System.out.println("getLock: " + Thread.currentThread().getId());
//从数据库拿去数据
List<User> users = userService.xxxxx(xxxxx);
// 写缓存
try {
valueOperations.set(redisKey, users, 30000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error("redis set key error", e);
}
}
} catch (InterruptedException e) {
log.error("doCacheRecommendUser error", e);
} finally {
// 只能释放自己的锁
if (lock.isHeldByCurrentThread()) {
System.out.println("unLock: " + Thread.currentThread().getId());
lock.unlock();
}
}
}
}