zoukankan      html  css  js  c++  java
  • Springboot 线程池配置

    最近的项目里要手动维护线程池,然后看到一起开发的小伙伴直接用Java了,我坚信Springboot不可能没这功能,于是查了些资料,果然有,这里给一下。

    首先我们都知道@Async标签能让方法异步执行,但是这个标签用的是Springboot默认的线程池,想自己实现线程池就要在项目里创建一个TaskExecutor或它的子类的Bean,像这样:

        @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里提供了四种默认的策略,非常粗暴:

        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);
                }
            }
        }
    
    • CallerRunsPolicy是让调用方法的线程自己运行。
    • AbortPolicy丢弃任务抛出异常。
    • DiscardPolicy:丢弃任务不报错。
    • DiscardOldestPolicy:丢弃队列最前面任务,之后尝试执行。

    顺便说一下,查源码可知,默认的策略是AbortPolicy,也就是最粗暴的那个,不过考虑到通常是不要让拒绝发生的,这里用粗暴的方案问题不大。为了实现方便配置,可以用yml对其进行配置:

    @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
    

    以上。

  • 相关阅读:
    NVIDIA Jetson TX2刷机
    安装python2和3在centos7里面的问题
    js和DOM结合实现评论功能 (可以添加,删除)
    js实现计时
    js获取星期日期
    js登录界面演示
    下拉列表演示
    html表单练习
    一个底层w32汇编的小例子,演示 原创
    invoke和call的区别
  • 原文地址:https://www.cnblogs.com/cielosun/p/9055645.html
Copyright © 2011-2022 走看看