gpt4 book ai didi

java - Spring Bean 内的 ScheduledExecutorService 在执行几次后不起作用

转载 作者:行者123 更新时间:2023-12-01 18:20:59 36 4
gpt4 key购买 nike

我正在尝试在 Spring @Bean 内安排一个任务,该任务将更新从 Bean 返回的实例的属性。

我能够运行这段代码,并且执行器工作正常几次,但之后,它突然停止加载。

这里到底有什么问题?有没有更好的方法来解决这个问题?

@Bean(name="service")
public Service getService(){
Service service = new Service();
ScheduledExecutorService serviceLoader = Executors.newScheduledThreadPool(1);
serviceLoader.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
service.loadAllLiveEvents();
}
}, 0, 1, TimeUnit.HOURS);

return service;
}

最佳答案

serviceLoader 的生命周期看起来很奇怪 - 它在方法或服务期间被初始化,然后安排一些工作,然后返回服务。对该池的引用会发生什么情况?什么时候可以调用关机?

此外,第一次迭代会立即运行,并且当应用程序上下文尚未准备好时会发生这种情况,这可能会导致不可预测的结果,具体取决于迭代期间运行的实际代码。

我无法确定根据此代码片段会发生什么,但这里有一些可能的解决方案:

  1. 使用@Scheduled注解,运行计划任务是Spring内置的功能。教程有很多,这里有one of them

  2. 如果你一定要使用线程池,我建议如下配置:

@Configuration
public class MyConfiguration {
@Bean
public Service service() {
return new Service();
}
@Bean(destroyMethod="shutdownNow") // or shutdown - now spring will close the pool when the app context gets closed
@Qualifier("serviceLoaderPool")
public ScheduledExecutorService serviceLoader() {
return Executors.newScheduledThreadPool(1);
}

@EventListener
public void onAppContextStarted(ApplicationReadyEvent evt) {
ScheduledExecutorService loader =
(ScheduledExecutorService)evt.getApplicationContext().getBean("serviceLoaderPool");
Service service = evt.getApplicationContext.getBean(Service.class);
loader.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
service.loadAllLiveEvents();
}
}, 0, 1, TimeUnit.HOURS);
}
}

通过这种方法,您可以确保在应用程序上下文准备就绪时服务将开始刷新。

执行器服务的生命周期也定义良好,Spring 将其作为常规单例 bean 进行管理,因此只要应用程序上下文启动并运行,它就不会被 GC。

destroy 方法的存在保证了正常关闭(同样,spring 会为你调用它)。

关于java - Spring Bean 内的 ScheduledExecutorService 在执行几次后不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60291123/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com