schedule
1、方式一
使用redission的特性来控制集群部署时的多次调用
缺点:单机的程序会在此处等待,导致其他任务没办法执行,原因是@Scheduled默认是单线程调度的
// 启动延时30秒执行,之后每隔60秒执行一次
@Scheduled(initialDelay = 30 * 1000, fixedDelay = 60 * 1000)
public void scheduledSync() {
RLock lock = redissonClient.getLock(KEY);
if (lock.tryLock()) {
try {
} catch (Exception e) {
} finally {
lock.unlock();
}
}
}
1.1、方式一可配置@Scheduled的多线程调用模式
@Bean
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
return taskScheduler;
}
2、方式二
使用线程池的特性来解决本次任务已执行完成,不耽误程序调度其他任务的执行;由于@Scheduled默认是单线程调度的,长时间占用此任务的话,其他任务都没法调用
// 自定义线程池,参数含义:
// 一个核心线程;
// 最大是一个线程;
// 线程回收空闲时间间隔零秒;
// 使用阻塞队列,队列最大存放任务量为一个;
// 在线程数已满、队列已满的情况下采取丢弃队列中旧的任务
ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new LinkedBlockingQueue(1), new ThreadPoolExecutor.DiscardOldestPolicy());
// 启动延时30秒执行,之后每隔60秒执行一次
@Scheduled(initialDelay = 30 * 1000, fixedDelay = 60 * 1000)
public void scheduledMethod() {
executor.submit(() -> {
try {
int pageNo = 1;
int pageSize = 50;
List<Object> list;
do {
PageHelper.startPage(pageNo++, pageSize, false);
list = selectData();
list.foreach(obj->execMechod(obj));
} while (!list.isEmpty() && list.size() >= pageSize);
} catch (Exception e) {
log.error("", e);
}
});
}
3、调度执行的方法
public void execMechod(Object obj) {
RLock lock = redissonClient.getLock(KEY + obj.getId());
if (lock.tryLock()) {
try {
// 是否需要再次验证数据状态
int count = updateStatusData();
if (count == 1) {
// TODO 执行后续代码
}
} catch (Exception e) {
log.error("", e);
} finally {
lock.unlock();
}
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)