Жизненный цикл serviceLoader выглядит странно - он инициализируется прямо во время метода или сервиса, затем планирует некоторую работу, а затем сервис возвращается. Что происходит со ссылкой на этот пул? когда остановка может быть вызвана?
Кроме того, первая итерация запускается немедленно, и это происходит, когда контекст приложения еще не готов, это может привести к непредсказуемым результатам в зависимости от фактического кода, который выполняется во время итерации.
Я не могу точно сказать, что происходит на основе этого фрагмента кода, но вот несколько возможных решений:
Использовать аннотацию @Scheduled
, запуск запланированных задач - это функция встроенной пружины , Есть много учебных пособий, вот один из них
Если вам абсолютно необходимо использовать пул потоков, я предлагаю следующую конфигурацию:
@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 управляет им как обычным одноэлементным компонентом, поэтому он не будет редактироваться G C, пока контекст приложения работает.
Наличие метода destroy гарантирует постепенное завершение работы (снова , весна назовет это для вас).