最近的项目里要手动维护线程池,而后看到一块儿开发的小伙伴直接用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