简介
定时线程池
Java定时任务实现原理-Timer、ScheduledThreadPoolExecutor
使用场景:分布式锁
springcloud -服务与注册中心
DelayedWorkQueue
heap -》 堆结构
存储数据结构是一个数组
代码示例
ScheduledExecutorService 延时队列,定时任务基本实现
/**
* @author August
* @version 1.0
* @description: 自动补货定时任务
* @date 2021/5/27 11:58
*/
@Service
public class UdiSyncSchecdule {
@Value("#{${sys.task.udi-sync.period}}")
private Long syncPeriod;
@Autowired
private UdiSyncService udiSyncService;
//private ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
1, new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(false).build());
/**
* 定时任务
*/
public void doSyncTaskRegular() {
pool.scheduleAtFixedRate(() -> {
try {
udiSyncService.syncUdiInfo();
} catch (Exception e) {
Log4jUtil.error("定时任务出错", e);
}
}, InitService.syncInitDelay, syncPeriod, TimeUnit.MILLISECONDS);
}
}
ScheduledExecutorService 延时队列,可取消、重启定时任务
/**
* @author August
* @version 1.0
* @description: 自动补货定时任务
* @date 2021/5/27 11:58
*/
public class AutoSupplementSchedule {
private static AutoSupplementSchedule instance;
private AutoSupplementSchedule() {
}
public static synchronized AutoSupplementSchedule getInstance() {
if(instance == null) {
instance = new AutoSupplementSchedule();
}
return instance;
}
//private ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
1, new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(false).build());
/**
* 重启自动补货定时任务,执行此方法会重新读取系统参数配置,并根据参数配置重启自动补货
*/
public void restartAutoSupplement() {
if(!InitService.autoSupplementEnableFlag) {
return;
}
if(IsOrNotSwitchEnum.YES.getIndex().equals(SysCtrlParamUtil.getValueByName(SysCtrlParamNameEnum.AUTO_SUPPLEMENT_SWITCH.getIndex()))) {
doAutoSupplementRegular();
} else {
cancelTask();
}
}
/**
* 取消原有定时任务
*/
private void cancelTask() {
if(scheduledFuture != null && !scheduledFuture.isCancelled()) {
Log4jUtil.info("取消自动补货定时任务");
scheduledFuture.cancel(false);
}
}
/**
* 定时任务
*/
private void doAutoSupplementRegular() {
long delayTime = getDelayTime();
if(delayTime <= 0) {
Log4jUtil.error("延时时间错误,无法执行自动补货定时任务");
return;
}
cancelTask();
Log4jUtil.info("启动/重启自动补货定时任务");
scheduledFuture = pool.scheduleAtFixedRate(() -> {
doSupplement();
}, delayTime, delayTime, TimeUnit.MILLISECONDS);
}
/**
*自动补货
*/
private void doSupplement() {
try {
Log4jUtil.info("自动补货开始执行");
SysSafetyStockService sysSafetyStockService = SpringContextUtil.getBean(SysSafetyStockService.class);
sysSafetyStockService.autoSupplement();
Log4jUtil.info("自动补货执行成功");
} catch (Exception e) {
Log4jUtil.error("自动补货失败!", e);
}
}
/**
* 获取补货周期
* @return
*/
private long getDelayTime(){
long delayTime = 24*60*60*1000;
long period = Long.valueOf(SysCtrlParamUtil.getValueByName(SysCtrlParamNameEnum.SUPPLEMENT_PERIOD.getIndex()));
String periodUnit = SysCtrlParamUtil.getValueByName(SysCtrlParamNameEnum.SUPPLEMENT_PERIOD_UNIT.getIndex());
if(SupplementPeriodUnitEnum.DAY.getIndex().equals(periodUnit)) {
delayTime = period * 24*60*60*1000;
} else if(SupplementPeriodUnitEnum.HOUR.getIndex().equals(periodUnit)) {
delayTime = period *60*60*1000;
} else if(SupplementPeriodUnitEnum.MINUTE.getIndex().equals(periodUnit)) {
delayTime = period *60*1000;
} else {
Log4jUtil.error("补货周期单位参数错误" + periodUnit);
}
return delayTime;
}
}