springAsync使用

782 阅读2分钟

1.启动项加上@EnableAsync注解

@EnableAsync
public class AppStart extends SpringBootServletInitializer{


2.自定义异步线程池

Spring 已经实现的异常线程池:
1. SimpleAsyncTaskExecutor:不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程。
2. SyncTaskExecutor:这个类没有实现异步调用,只是一个同步操作。只适用于不需要多线程的地方
3. ConcurrentTaskExecutor:Executor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类
4. SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的类。线程池同时被quartz和非quartz使用,才需要使用此类
5. ThreadPoolTaskExecutor :最常使用,推荐。 其实质是对java.util.concurrent.ThreadPoolExecutor的包装


ThreadPoolExecutor池子的处理流程如下:  

1)当池子大小小于corePoolSize就新建线程,并处理请求

2)当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去从workQueue中取任务并处理

3)当workQueue放不下新入的任务时,新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize就用RejectedExecutionHandler来做拒绝处理

4)另外,当池子的线程数大于corePoolSize的时候,多余的线程会等待keepAliveTime长的时间,如果无请求可处理就自行销毁

其会优先创建 CorePoolSiz 线程, 当继续增加线程时,先放入Queue中,当 CorePoolSiz 和 Queue 都满的时候,就增加创建新线程,当线程达到MaxPoolSize的时候,就会抛出错 误 org.springframework.core.task.TaskRejectedException

另外MaxPoolSize的设定如果比系统支持的线程数还要大时,会抛出java.lang.OutOfMemoryError: unable to create new native thread 异常。

@Configuration
public class AsyncConfig {
	 /**
	   * 自定义异步线程池
	   * @return
	   */
	@Bean
	public AsyncTaskExecutor taskExecutor() {
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(2);
		executor.setMaxPoolSize(20);
		executor.setQueueCapacity(100);
		executor.setThreadNamePrefix("threadPoolExecutor-");
		executor.initialize();
		return executor;
	}
	 
}

3.使用

@Component
    public class AsyncDemo {
        private static final Logger log = LoggerFactory.getLogger(AsyncDemo.class);
     
        /**
         * 最简单的异步调用,返回值为void
         */
        @Async
        public void asyncInvokeSimplest() {
            log.info("asyncSimplest");
        }
     
        /**
         * 带参数的异步调用 异步方法可以传入参数
         * 
         * @param s
         */
        @Async
        public void asyncInvokeWithParameter(String s) {
            log.info("asyncInvokeWithParameter, parementer={}", s);
        }
     
        /**
         * 异常调用返回Future
         * 
         * @param i
         * @return
         */
        @Async
        public Future<String> asyncInvokeReturnFuture(int i) {
            log.info("asyncInvokeReturnFuture, parementer={}", i);
            Future<String> future;
            try {
                Thread.sleep(1000 * 1);
                future = new AsyncResult<String>("success:" + i);
            } catch (InterruptedException e) {
                future = new AsyncResult<String>("error");
            }
            return future;
        }
     
    }