springboot 定时器_springBoot的定时器应该这样写
公司的结算模块业务线概括:需要一个定时任务去监测符合结算条件的数据,然后进行各个用户的分账。
这里使用到了springBoot 集成的定时器 Spring Task ,为了数据安全,也更高效,使用到了多线程执行。
首先创建一个初始化线程的类
(图1)
@Configuration
public class ScheduleConfig implements SchedulingConfigurer, AsyncConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
TaskScheduler taskScheduler = taskScheduler();
scheduledTaskRegistrar.setTaskScheduler(taskScheduler);
}
/**
* 初始化线程池
* @return
*/
@Bean(destroyMethod = "shutdown")//通知关闭线程池
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5);
// 设置线程名前缀
scheduler.setThreadNamePrefix("task-");
// 等待所有线程执行完
scheduler.setWaitForTasksToCompleteOnShutdown(true);
return scheduler;
}
/**
* 异步任务
* @return
*/
@Override
public Executor getAsyncExecutor() {
Executor executor = taskScheduler();
return executor;
}
/**
* 异常处理
* @return
*/
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SimpleAsyncUncaughtExceptionHandler();
}
初始化5个线程来处理业务。
这里我们可以简单的看一下源码,为什么要初始化线程的数量
因为(图1)实现了SchedulingConfigurer 这个类,(图2) SchedulingConfigurer 类并没有对线程数量进行约束,所以我们为了提高业务处理量,我们手动创建线程数量来处理数据。我们只需图1 重写 SchedulingConfigurer 里的 configureTasks 方法,就可以完成创建线程数量。
(图2)
package org.springframework.scheduling.annotation;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@FunctionalInterface
public interface SchedulingConfigurer {
void configureTasks(ScheduledTaskRegistrar var1);
}
创建一个 DynamicScheduledTask 类 实现 SchedulingConfigurer 我们就可以重写线程类了。
@Configuration
@EnableScheduling
public class DynamicScheduledTask implements SchedulingConfigurer {
// 定时器执行频率,半小时一次 0 0/30 * * * ?
private static final String DEFAULT_CRON = "0 0/5 * * * ?";//五分钟执行一次
private String cron = DEFAULT_CRON;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
scheduledTaskRegistrar.addTriggerTask(new Runnable() {
@Override
public void run() {
doBiz();
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
// 定时任务触发,可修改定时任务的执行周期
CronTrigger trigger = new CronTrigger(cron);
Date nextExecDate = trigger.nextExecutionTime(triggerContext);
return nextExecDate;
}
});
}
/**
* 定时器执行方法
*/
public void doBiz() {
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
}
好奇的童鞋可以点进去看一下源码,大概理解其思想,是有帮助的。
下面我们开始编写业务类,就是处理结算数据的代码模块
package com.example.fuxing.taskConfig;
public class test {
/**
* 扫描子订单表下订单状态值为4的数据,进行结算分账
*/
@Component
@Service
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public class ScanOrderTask extends DynamicScheduledTask {
@Resource
TimerService timerService;
private Logger log = LoggerFactory.getLogger(this.getClass());
public void doBiz() {
try {
DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
log.info("定时器开始执行" + sdf.format(new Date()) + "秒");
List fxOrderMedia = timerService.runTimer();
if (null != fxOrderMedia && fxOrderMedia.size() != 0) {
//执行代理商及平台分成
selectFxOrderMedia("");
}
} catch (Exception e) {
throw new ResponseJsonException(FXErrorCode.Error, e.getMessage());
}
}
/**
* 查询订单的信息
*
* @param mediaOrdercode
* @return
*/
FxOrderMedia selectFxOrderMedia(String mediaOrdercode) {
//查询订单的信息
FxOrderMedia fxOrderMedia = timerService.selectFxOrderMedia(mediaOrdercode);
JSONObject json = JSONObject.fromObject(fxOrderMedia);
log.info("------所要结算的订单信息-------" + json.toString());
//判断此订单是否为代理商下的订单
if (!StringUtils.isEmpty(fxOrderMedia.getAgentcode()) && fxOrderMedia.getCommissionRatio() != new BigDecimal(0)) {
//代理商分成
Map returnDate = agencyShare(fxOrderMedia);
if ("false".equals(returnDate.get("return").toString())) {
throw new ResponseJsonException(FXErrorCode.Error, "代理商分成失败!");
}
}
//如果不是代理商用户
Map map = platformDivision(fxOrderMedia);
if ("false".equals(map.get("return").toString())) {
throw new ResponseJsonException(FXErrorCode.Error, "平台分成失败!");
}
return fxOrderMedia;
}
/**
* 代理商分成业务
*/
private Map agencyShare(FxOrderMedia fxOrderMedia) {
//分账A
return null;
}
/**
* 平台分成业务
*/
private Map platformDivision(FxOrderMedia fxOrderMedia) {
//分账B
return null;
}
}
}
如有不对,请其指出,希望我们在前进的道路上互帮互助。
springboot 定时器_springBoot的定时器应该这样写相关推荐
- TCP的定时器系列 — SYNACK定时器
转载 主要内容:SYNACK定时器的实现,TCP_DEFER_ACCPET选项的实现. 内核版本:3.15.2 我的博客:http://blog.csdn.net/zhangskd 在上一篇博客中,已 ...
- 补充设定 timer1 定时器和 timer2 定时器定时做多件事
文章目录 7. 补充设定 timer1 定时器和 timer2 定时器定时做多件事(教程) 7.1 补充如何暂时停止这 timer1 的CTC中断 ? 7.2 那要如何又重新启动 timer1 的CT ...
- 51单片机定时器/计数器(定时器中断)
51单片机定时器/计数器(中断系统:定时器中断) 实现功能 通过定时器终端控制LED灯 D1 间隔一秒闪烁 单片机型号:STC89C52 定时器介绍 1.51单片机定时器原理 定时器实质上就是一个加1 ...
- STM32入门笔记04_TIM定时器+案例:TIM定时器定时中断、定时器外部时钟
TIM定时器 TIM简介 TIM(Timer) 定时器 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断 16位计数器.预分频器.自动重装寄存器的时基单元,在72MHz(系统主频)计数时 ...
- LPC2103学习之定时器0和定时器1
2019独角兽企业重金招聘Python工程师标准>>> 这两天学习LPC2103的定时器.开始看前面的寄存器介绍看的有点头晕,一会儿就搞混了.不过当我看到后面用图片描述定时器相关寄存 ...
- JS 设置定时器和清除定时器
在做项目中难免会碰到需要实时刷新,动画依次出现等等需求,这时候就需要定时器登上我们的代码舞台了,所以今天我们就先来了解一下JS定时器的设置和清除吧. 一.启用定时器 window对象提供了两个方法来实 ...
- android h5app息屏定时器,H5案例分享:JS设置定时器和清除定时器
JS设置定时器和清除定时器 在做项目中难免会碰到需要实时刷新,动画依次出现等等需求,这时候就需要定时器登上我们的代码舞台了,所以今天我们就先来了解一下JS定时器的设置和清除吧. 一.启用定时器 win ...
- 三菱PLC的通用定时器与累积定时器的异同点(当前值寄存器与设定值寄存器是什么关系)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.定时器 二.通用定时器 三.累积定时器 一.定时器 定时器分类为通用型定时器(T0-T245)与累积定时器(T246-2 ...
- java定时器、Spring定时器和Quartz定时器
当前java程序中能够实现定时的主要有三种方式,分别是:java定时器,spring定时器,quartz定时器. 下面依次讲讲他们的应用! java定时器的应用 其实java很早就有解决定时器任 ...
最新文章
- SCA与spring集成(在spring中开发SOA)
- ABAP算法:找出递归的物料
- 华为鸿蒙一再延期,华为P50再次延期,鸿蒙系统正式版加持,有望与新平板一同登场...
- WebApiClient与Asp.net core DI的结合
- 【debug】使用lambda在循环中传参时,参数总为同一个值
- Python批量检查docx文档中文本框的内容是否正确
- POJ 2425 A Chess Game(有向图SG函数)题解
- 实现UniqueAttribute唯一性约束-优化版
- 数据资产管理直面企业哪些痛点
- VIM 插件管理工具——vim-plug
- bgp高防-服务器单线、双线、三线、BGP线路哪个更好?
- ios13 微信提示音插件_ios13怎么改微信提示音
- Interfacing with Pixhawk using the NSH
- 信通院郭雪:软件供应链安全标准体系建设与洞察
- 【饿了么】—— Vue2.0高仿饿了么核心模块移动端Web App项目爬坑(一)
- android notify() notifyAll()的区别
- Ubuntu 18.04 安装RealSense D435教程
- 三点确定圆心和半径(模版)
- 地震地图告诉你,地震带离你家有多远?危险指数最高的城市竟然是……
- R: 更改行名及矩阵数据提取的易错点——下标出界