Java |
您所在的位置:网站首页 › spring中的线程池 › Java |
作者:Mars酱 声明:本文章由Mars酱原创,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我! 前言多线程解决了并发阻塞问题,但是不能方便的表达我们的定时方式,目前单体架构定时任务用的多的就应该是Spring Task中的注解方式了吧? @Scheduledscheduled注解常用的几个: cron:支持灵活的cron表达式 fixedRate:固定频率。比如:2号线地铁每5分钟一趟,那么2号线的所有列车其实已经安排好了时刻表,所以每台准点发就行了,但是如果其中一趟晚点,那么下一趟就会延迟。 fixedDelay:固定时延。它的意思是表示上个任务结束,到下个任务开始的时间间隔。无论任务执行花费多少时间,两个任务间的间隔始终是一致的。 搞一搞 @Scheduled(fixedDelay = 1000 * 5) public void timerTaskA(){ // Mars酱 做业务a... }每间隔5秒执行一次 @Scheduled(cron = "0 0 1 * * ? ") public void timerTaskB(){ // Mars酱 做业务b... }这是支持cron表达式的,每天凌晨1点执行 Scheduled会阻塞吗?我们来分析下Spring的源代码吧,如果我们用fixedRate或者fixedDelay,可以在 Spring 的@Scheduled的源代码实现部分找到如下代码: 会在一个registrar对象中添加注解相对应的对象,这个registrar是ScheduledTaskRegistrar对象: private final ScheduledTaskRegistrar registrar = new ScheduledTaskRegistrar();而这个ScheduledTaskRegistrar对象中有一个ScheduledExecutorService属性: @Nullable private ScheduledExecutorService localExecutor;这个就是我们上篇中提到的多线程定时任务实现,继续在在ScheduledTaskRegistrar中又找到创建这个对象的方法: /** * Schedule all registered tasks against the underlying * {@linkplain #setTaskScheduler(TaskScheduler) task scheduler}. */ @SuppressWarnings("deprecation") protected void scheduleTasks() { if (this.taskScheduler == null) { // 创建了一个单线程对象 this.localExecutor = Executors.newSingleThreadScheduledExecutor(); this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor); } if (this.triggerTasks != null) { for (TriggerTask task : this.triggerTasks) { addScheduledTask(scheduleTriggerTask(task)); } } if (this.cronTasks != null) { for (CronTask task : this.cronTasks) { addScheduledTask(scheduleCronTask(task)); } } if (this.fixedRateTasks != null) { for (IntervalTask task : this.fixedRateTasks) { addScheduledTask(scheduleFixedRateTask(task)); } } if (this.fixedDelayTasks != null) { for (IntervalTask task : this.fixedDelayTasks) { addScheduledTask(scheduleFixedDelayTask(task)); } } }这里第一个if判断就是创建那个localExecutor对象,使用的是newSingleThreadScheduledExecutor。在 Java | 一分钟掌握异步编程 | 3 - 线程异步 - 掘金 (juejin.cn)中提到过,这是创建单线程的线程池方式。那么一个单线程去跑多个定时任务是不是就会产生阻塞?来证明一下。 改写一下之前的例子,两个都是5秒执行,其中一个任务在执行的时候再延迟10秒,看是不是会影响到另一个线程的定时任务执行。改写后的代码如下: import org.springframework.boot.SpringApplication; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import java.util.Date; /** * @author mars酱 */ @EnableScheduling public class MarsSpringScheduled { public static void main(String[] args) { SpringApplication.run(MarsSpringScheduled.class, args); } @Scheduled(fixedDelay = 5000) public void timerTaskA() throws InterruptedException { System.out.println(">> 这是a任务:当前时间:" + new Date()); Thread.sleep(10000); } @Scheduled(fixedDelay = 5000) public void timerTaskB() { System.out.println(" |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |