1. Problem background
During the development process, we often need to perform timing tasks, such as timed refreshing caches, cleaning temporary data, etc. Spring provides@Scheduled
Annotation, it can easily implement timing tasks. However, sometimes we find that the task is executed only once and will not be triggered later. For example:
@Component @Slf4j public class MediaAdIdCache { @Scheduled(fixedRate = 60 * 1000) // Expected to be executed once per minute public void refreshCache() { ("Refresh the cache..."); } }
ifrefreshCache()
It was only executed once, and we need to troubleshoot the cause and fix it.
2. Basic usage of Spring timed tasks
Spring's@Scheduled
Annotation supports three ways:
-
fixedRate
: Fixed frequency execution (fixed time interval after the last task started) -
fixedDelay
: Fixed delayed execution (fixed time interval after the last task ends) -
cron
: Cron expression controls execution time
Example:
@Scheduled(fixedRate = 5000) // Execute every 5 secondspublic void task1() { ("Fixed Rate Task"); } @Scheduled(fixedDelay = 3000) // Execute again 3 seconds after the last task is overpublic void task2() { ("Fixed Delay Task"); } @Scheduled(cron = "0 * * * * ?") // Execute once per minutepublic void task3() { ("Cron Task"); }
3. Why are timed tasks only executed once?
3.1 Scheduling support is not enabled (@EnableScheduling)
Cause of the problem:
- Spring Boot will not automatically scan by default
@Scheduled
Annotation, scheduling support must be enabled explicitly.
Solution:
- Add on main class or configuration class
@EnableScheduling
:
@SpringBootApplication @EnableScheduling // Key notespublic class MyApp { public static void main(String[] args) { (, args); } }
3.2 The task throws an uncaught exception
Cause of the problem:
- If the timing task throws an uncaught exception, Spring may terminate subsequent scheduling.
Example:
@Scheduled(fixedRate = 5000) public void errorTask() { throw new RuntimeException("Simulate exception"); }
Solution:
- use
try-catch
Catch exception:
@Scheduled(fixedRate = 5000) public void safeTask() { try { // Business logic } catch (Exception e) { ("Task execution failed", e); } }
3.3 Thread pool problem causes task blockage
Cause of the problem:
- Spring uses a single thread to execute timing tasks by default. If a task takes too long, other tasks will be blocked.
Solution:
- Custom thread pool:
@Configuration public class SchedulerConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { ((5)); } }
3.4 Redis connection failure causes task interruption
Cause of the problem:
- If the timing task depends on external services (such as Redis, database), connection failure may cause the task to be interrupted.
Solution:
- Ensure external services are available and add retry mechanisms:
@Scheduled(fixedRate = 60 * 1000) public void refreshCache() { try { Set<String> ids = ().members("key"); // Business logic } catch (Exception e) { ("Redis operation failed", e); } }
4. Solution summary
question | Solution |
---|---|
Not enabled@EnableScheduling
|
Add in main class@EnableScheduling
|
The task throws an exception | usetry-catch Catch exceptions |
Single thread blocking | Configure multi-threaded pools |
External dependency failure | Check connections and add error handling |
5. Complete code example
5.1 Main startup class (enable scheduling)
@SpringBootApplication @EnableScheduling public class MyApp { public static void main(String[] args) { (, args); } }
5.2 Timed task class (with exception handling)
@Component @Slf4j public class MediaAdIdCache { private final RedisTemplate<String, String> redisTemplate; public MediaAdIdCache(RedisTemplate<String, String> redisTemplate) { = redisTemplate; } @Scheduled(fixedRate = 60 * 1000) // Execute once per minute public void refreshCache() { try { Set<String> ids = ().members("flowfilter:mediaAdId"); ("Cache refresh successfully,quantity: {}", ()); } catch (Exception e) { ("Failed to refresh the cache", e); } } }
5.3 Custom thread pool (prevent blocking)
@Configuration public class SchedulerConfig implements SchedulingConfigurer { @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { ((5)); } }
6. Summary
Spring's@Scheduled
The timing tasks are only executed once, usually because:
- Scheduling not enabled (
@EnableScheduling
Missing) - Task throws exception (not handled correctly)
- Thread pool problem (single thread blocking)
- External dependency failure (such as Redis connection problem)
Through this article's analysis and solutions, you can effectively avoid the problem of timed task interruption and ensure that the task is executed as expected. If there are still problems, it is recommended to combine logging and debugging to further troubleshoot.
The above is the detailed content of the reason analysis and solution for Spring timed tasks only executed once. For more information about Spring timed tasks only executed once, please pay attention to my other related articles!