我們的訂單服務,一般會有一個待支付訂單,而這個待支付訂單是有時間限制的,例如阿里巴巴的訂單是五天,淘寶訂單是一天,拼多多訂單是一天,美團訂單是15分鐘…
基金系統中,如何同時更新多個儲存分區中的基金資訊…
總的來說,實際開發中定時器需要解決多個定時器同時並發的問題,也要解決定時器之間的衝突問題
問題不大,說到並發那就離不開多線程了…慢慢看看就懂了
#我們清楚的看到執行結果都是scheduling-1
就此可以判定,Springboot定時器預設的是單執行緒的
但是問題就來了,如果在執行緒爭奪資源後,某個執行緒需要比較長時間才能執行完,那其他的定時器怎麼辦,都只能進入等待狀態,時間越久,累計等待的定時器越多,這就容易引起雪崩…
#其實只需要添加一個配置類別然後加註解就可以解決問題了
具體程式碼如下:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.Date; @Component public class SchedulerTaskController { private Logger logger= LoggerFactory.getLogger(SchedulerTaskController.class); private static final SimpleDateFormat dateFormat=new SimpleDateFormat("HH:mm:ss"); private int count=0; @Scheduled(cron="*/6 * * * * ?") @Async("threadPoolTaskExecutor") public void process(){ logger.info("英文:this is scheduler task runing "+(count++)); } @Scheduled(fixedRate = 6000) @Async("threadPoolTaskExecutor") public void currentTime(){ logger.info("中文:现在时间"+dateFormat.format(new Date())); } }
具體程式碼如下:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; /**使用多线程的时候,往往需要创建Thread类,或者实现Runnable接口,如果要使用到线程池,我们还需要来创建Executors, * 在使用spring中,已经给我们做了很好的支持。只要要@EnableAsync就可以使用多线程 * 通过spring给我们提供的ThreadPoolTaskExecutor就可以使用线程池。*/ //@Configuration 表示该类是一个配置类 @Configuration @EnableAsync //所有的定时任务都放在一个线程池中,定时任务启动时使用不同都线程。 public class TaskScheduleConfig { private static final int corePoolSize = 10; // 默认线程数 private static final int maxPoolSize = 100; // 最大线程数 private static final int keepAliveTime = 10; // 允许线程空闲时间(单位:默认为秒),十秒后就把线程关闭 private static final int queueCapacity = 200; // 缓冲队列数 private static final String threadNamePrefix = "it-is-threaddemo-"; // 线程池名前缀 @Bean("threadPoolTaskExecutor") // bean的名称,默认为首字母小写的方法名 public ThreadPoolTaskExecutor getDemoThread(){ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(keepAliveTime); executor.setKeepAliveSeconds(queueCapacity); executor.setThreadNamePrefix(threadNamePrefix); //线程池拒绝任务的处理策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //初始化 executor.initialize(); return executor; } }
然後我們可以很清楚地看到:
以上是Spring Boot多個定時器衝突怎麼解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!