使用@Scheduling在@Scheduled(fixedRate = 10000)运行方法并通过实现SchedulingConfigurer设置@Scheduling线程
@Bean(destroyMethod="shutdown")
public Executor taskExecutor() {
return Executors.newScheduledThreadPool(10);
}
如果我使用Thread.sleep或Lock,除非Thread.sleep唤醒或锁定被清除,否则Executor不会创建其他线程。
有人可以解释内部工作,如果我有10个池大小,他们应该以10000毫秒的速度创建10个线程。
基本上这种行为来自ScheduledExecutorService
实现,它在春天内部使用。如果您将运行此代码,您将注意到相同的行为:
public static void main(String[] args) throws Exception {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
executor.schedule(() -> {
System.out.println("Running task in thread " + Thread.currentThread().getId());
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
System.out.println("interrupted while sleeping");
}
}, 1000, TimeUnit.MILLISECONDS);
Thread.sleep(10000);
executor.shutdownNow();
}
当您将任务提交到计划的线程池时,它将使用RunnableScheduledFuture
进行包装,并将其传递给delayedExecute
方法。如果当前工作人员数小于corePoolSize
,此方法会将任务添加到任务队列并启动新工作程序。工作者试图从队列中获取任务并处理它调用run
方法。有一个专用的DelayedWorkQueue
实现,只有在它们准备好执行时才返回任务。以下是run
RunnableScheduledFuture
方法的样子:
/**
* Overrides FutureTask version so as to reset/requeue if periodic.
*/
public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)
ScheduledFutureTask.super.run();
else if (ScheduledFutureTask.super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}
正如您所看到的,它在runAndReset
中调用实际任务逻辑,计算下一个运行时间并再次向队列提交相同的更新任务(reExecutePeriodic
几乎与schedule
相同)。对于所有执行只有一个周期性任务,在上一次执行完成后,一次又一次地重新提交更新时间。因此,此类线程池在任何给定时刻仅运行每个任务类型的单个实例,并且仅针对不同类型的任务进行扩展。
如果你对春季计划任务如何看待ScheduledTaskRegistrar
类,特别是在scheduleFixedDelayTask
方法感兴趣。
在您使用threadpool的情况下:默认情况下,您的池中将有10个线程(已初始化)。 @scheduled第一次执行时,这个函数将在你的池中的一个线程中执行(现在剩下9个线程),如果函数已经完成并再次执行@scheduled,你的函数将在你的其他线程中执行你的游泳池,所以现在游泳池里剩下8个线程。 (8个空闲,2个正在运行的线程)
如果您不使用线程池,则只使用一个线程。
弹簧文档:
如果未提供“pool-size”属性,则默认线程池将只有一个线程。调度程序没有其他配置选项。
https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/html/scheduling.html
• 在spring boot微服务中,休息调用的调度不工作。
• 启用 Spring Security 后,Spring Boot 不提供 HTML
• 如何去除Spring Security 6和Spring Boot 3中的ROLE_前缀?
• 我收到 CORS Error only GET 请求,我什至在 Spring 中编写了 CORS 配置
• Swagger 在 Spring Security 6 之后不工作
• 使用Spring Session是否需要在HttpSecurity中配置sessionManagement?
• Spring Boot 启用 <async-supported> 就像在 web.xml 中一样
• 基于 spring boot 应用程序中的 spring 配置文件的 Wiremock 设置
• 单元测试,将属性转换为 yml 后无法加载 ApplicationContext
• 为什么 spring xml 配置抛出异常,其中一个接口和该接口的一个实现,但不在 java 配置中抛出异常?
• 在 Java 和 Spring Boot 中动态过滤 JSON 对象 [关闭]