@EnableAsync @Asnc 以及4種拒絕策略


根據不同的場景,可以選擇不同的拒絕策略,如果任務非常重要,線程池隊列滿了,可以交由調用者線程同步處理.

如果是一些不太重要日志,可以直接丟棄掉.

如果一些可以丟棄,但是又需要知道被丟棄了,可以使用ThreadPoolExecutor.AbortPolicy(),在異常處理中記錄日志

/**
 * laizhenwei 2018-1-1 12:46:02
 */
@Configuration
@EnableAsync
public class ExecutorConfig implements AsyncConfigurer {

    /**
     * 替換默認線程池,線程隊列滿了以后交給調用者執行,也就是同步執行
     * @return
     */
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(7);
        executor.setMaxPoolSize(42);
        executor.setQueueCapacity(11);
        executor.setThreadNamePrefix("Executor-");
        executor.setAllowCoreThreadTimeOut(false);
        executor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

    /**
     * 隊列滿了以后,拋棄任務,但是會拋出 rejectedExecution 如果不處理會中斷線程
     * @return
     */
    @Bean
    public Executor myExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(20);
        executor.setThreadNamePrefix("MyExecutor-");
        executor.setAllowCoreThreadTimeOut(false);
        executor.setRejectedExecutionHandler( new ThreadPoolExecutor.AbortPolicy());
        executor.initialize();
        return executor;
    }

    /**
     * 隊列滿了,直接丟棄當前任務,不拋出異常
     * @return
     */
    @Bean
    public Executor myExecutor1() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(20);
        executor.setThreadNamePrefix("MyExecutor1-");
        executor.setAllowCoreThreadTimeOut(false);
        executor.setRejectedExecutionHandler( new ThreadPoolExecutor.DiscardPolicy());
        executor.initialize();
        return executor;
    }

    /**
     * 隊列滿了,丟棄最老的任務,不拋出異常
     * @return
     */
    @Bean
    public Executor myExecutor2() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(2);
        executor.setQueueCapacity(20);
        executor.setThreadNamePrefix("MyExecutor2-");
        executor.setAllowCoreThreadTimeOut(false);
        executor.setRejectedExecutionHandler( new ThreadPoolExecutor.DiscardOldestPolicy());
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new MyAsyncUncaughtExceptionHandler();
    }

    public static class MyAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler{
        @Override
        public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
            System.out.println(throwable.getMessage());
        }
    }

}

調用方式使用 value 是bean 的名稱

 @Async("myExecutor")

如果異步處理的方法,涉及到jdbc事務,那么請先理解Spring事務的連接是保存在ThreadLocal中的原理,避免踩坑.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM