最近的項目裏要手動維護線程池,而後看到一塊兒開發的小夥伴直接用Java了,我堅信Springboot不可能沒這功能,因而查了些資料,果真有,這裏給一下。java
首先咱們都知道@Async
標籤能讓方法異步執行,可是這個標籤用的是Springboot默認的線程池,想本身實現線程池就要在項目裏建立一個TaskExecutor或它的子類的Bean,像這樣:less
@Bean public AsyncTaskExecutor threadPoolTaskExecutor(){ ThreadPoolTaskExecutor threadPoolTaskExecutor=new ThreadPoolTaskExecutor(); //加入此頭後此線程池成爲系統線程池 threadPoolTaskExecutor.setThreadNamePrefix("Anno-Executor"); threadPoolTaskExecutor.setCorePoolSize(corePoolSize); threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize); threadPoolTaskExecutor.setQueueCapacity(queueCapacity); threadPoolTaskExecutor.setKeepAliveSeconds(keepAliveSeconds); threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return threadPoolTaskExecutor; }
其中拒絕策略能夠改成手動編寫,像下面這樣:異步
threadPoolTaskExecutor.setRejectedExecutionHandler(new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { } });
JDK裏提供了四種默認的策略,很是粗暴:ide
public static class CallerRunsPolicy implements RejectedExecutionHandler { /** * Creates a {@code CallerRunsPolicy}. */ public CallerRunsPolicy() { } /** * Executes task r in the caller's thread, unless the executor * has been shut down, in which case the task is discarded. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { r.run(); } } } /** * A handler for rejected tasks that throws a * {@code RejectedExecutionException}. */ public static class AbortPolicy implements RejectedExecutionHandler { /** * Creates an {@code AbortPolicy}. */ public AbortPolicy() { } /** * Always throws RejectedExecutionException. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task * @throws RejectedExecutionException always */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } } /** * A handler for rejected tasks that silently discards the * rejected task. */ public static class DiscardPolicy implements RejectedExecutionHandler { /** * Creates a {@code DiscardPolicy}. */ public DiscardPolicy() { } /** * Does nothing, which has the effect of discarding task r. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { } } /** * A handler for rejected tasks that discards the oldest unhandled * request and then retries {@code execute}, unless the executor * is shut down, in which case the task is discarded. */ public static class DiscardOldestPolicy implements RejectedExecutionHandler { /** * Creates a {@code DiscardOldestPolicy} for the given executor. */ public DiscardOldestPolicy() { } /** * Obtains and ignores the next task that the executor * would otherwise execute, if one is immediately available, * and then retries execution of task r, unless the executor * is shut down, in which case task r is instead discarded. * * @param r the runnable task requested to be executed * @param e the executor attempting to execute this task */ public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) { e.getQueue().poll(); e.execute(r); } } }
順便說一下,查源碼可知,默認的策略是AbortPolicy,也就是最粗暴的那個,不過考慮到一般是不要讓拒絕發生的,這裏用粗暴的方案問題不大。爲了實現方便配置,能夠用yml對其進行配置:this
@Component @Data @ConfigurationProperties("thread-pool-factory") public class ThreadPoolFactory { private int corePoolSize; private int maxPoolSize; private int queueCapacity; private int keepAliveSeconds; @Bean public AsyncTaskExecutor threadPoolTaskExecutor(){ //...... } }
這裏@Data
標籤是lambok的標籤,快速生成getter和setter用。以上Component構建好後,能夠直接配置:線程
thread-pool-factory: #IO密集型應用,線程數爲2N+1 corePoolSize: 9 maxPoolSize: 18 queueCapacity: 100 keepAliveSeconds: 120
以上。code