介绍
小编给大家分享一下弹簧启动异步异步执行任务的操作方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
异步调用就是不用等待结果的返回就执行后面的逻辑,同步调用则需要等带结果再执行后面的逻辑。
通常我们使用异步操作都会去创建一个线程执行一段逻辑,然后把这个线程丢到线程池中去执行,代码如下:
ExecutorService ExecutorService=Executors.newFixedThreadPool (10); executorService.execute (()→{ 尝试{//业务逻辑 }捕捉(异常e) { e.printStackTrace (); 最后}{ } });
这样的方式看起来没那么优雅,尽管用了java的λ。在春天引导中有一种更简单的方式来执行异步操作,只需要一个@Async注解即可。
@Async 公共空间saveLog () { System.err.println (Thread.currentThread () . getname ()); }
我们可以直接在控制器中调用这个业务方法,它就是异步执行的,会在默认的线程池中去执行。需要注意的是一定要在外部的类中去调用这个方法,如果在本类调用是不起作用的,比如this.saveLog()。最后在启动类上开启异步任务的执行,添加@EnableAsync即可。
另外关于执行异步任务的线程池我们也可以自定义,首先我们定义一个线程池的配置类,用来配置一些参数,具体代码如下:
进口org.springframework.boot.context.properties.ConfigurationProperties; 进口org.springframework.context.annotation.Configuration;/* * *异步任务线程池配置 * * @author yinjihuan */@ configuration @ConfigurationProperties(前缀=皊pring.task.pool") 公开课TaskThreadPoolConfig {//核心线程数 私人int corePoolSize=5;//最大线程数 私人int maxPoolSize=50;//线程池维护线程所允许的空闲时间 私人int keepAliveSeconds=60;//队列长度 私人int queueCapacity=10000;//线程名称前缀 私人字符串threadNamePrefix=癋SH-AsyncTask产生绯闻;; 公共字符串getThreadNamePrefix () { 返回threadNamePrefix; } 公共空间setThreadNamePrefix(字符串threadNamePrefix) { 这一点。threadNamePrefix=threadNamePrefix; } 公共int getCorePoolSize () { 返回corePoolSize; } 公共空间setCorePoolSize (int corePoolSize) { 这一点。corePoolSize=corePoolSize; } 公共int getMaxPoolSize () { 返回maxPoolSize; } 公共空间setMaxPoolSize (int maxPoolSize) { 这一点。maxPoolSize=maxPoolSize; } 公共int getKeepAliveSeconds () { 返回keepAliveSeconds; } 公共空间setKeepAliveSeconds (int keepAliveSeconds) { 这一点。keepAliveSeconds=keepAliveSeconds; } 公共int getQueueCapacity () { 返回queueCapacity; } 公共空间setQueueCapacity (int queueCapacity) { 这一点。queueCapacity=queueCapacity; } }
然后我们重新定义线程池的配置:
进口java.lang.reflect.Method; 进口java.util.concurrent.Executor; 进口java.util.concurrent.ThreadPoolExecutor; 进口org.slf4j.Logger; 进口org.slf4j.LoggerFactory; 进口org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; 进口org.springframework.beans.factory.annotation.Autowired; 进口org.springframework.context.annotation.Configuration; 进口org.springframework.scheduling.annotation.AsyncConfigurer; 进口org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @ configuration 公共类AsyncTaskExecutePool实现AsyncConfigurer { 私人日志记录器=LoggerFactory.getLogger (AsyncTaskExecutePool.class); @ autowired 私人TaskThreadPoolConfig配置; @Override 公共执行人getAsyncExecutor () { ThreadPoolTaskExecutor执行人=new ThreadPoolTaskExecutor (); executor.setCorePoolSize (config.getCorePoolSize ()); executor.setMaxPoolSize (config.getMaxPoolSize ()); executor.setQueueCapacity (config.getQueueCapacity ()); executor.setKeepAliveSeconds (config.getKeepAliveSeconds ()); executor.setThreadNamePrefix (config.getThreadNamePrefix ());//线程池对拒绝任务(无线程可用)的处理策略,目前只支持AbortPolicy, CallerRunsPolicy//AbortPolicy:直接抛出java . util . concurrent。RejectedExecutionException异常——比;//CallerRunsPolicy:主线程直接执行该任务,执行完之后尝试添加下一个任务到线程池中,可以有效降低向线程池内添加任务的速度——比;//DiscardOldestPolicy:抛弃旧的任务,暂不支持,会导致被丢弃的任务无法再次被执行——比;//DiscardPolicy:抛弃当前任务,暂不支持,会导致被丢弃的任务无法再次被执行——比; 遗嘱执行人。setRejectedExecutionHandler(新ThreadPoolExecutor.CallerRunsPolicy ()); executor.initialize (); 返回执行人; } @Override 公共AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler(){//异步任务中异常处理 返回新AsyncUncaughtExceptionHandler () { @Override 公共空间handleUncaughtException (Throwable arg0, __arg1方法,对象…最长){ logger.error (“==========================? arg0.getMessage () +“=======================? arg0); logger.error(“异常方法:“+ arg1.getName ()); } }; } }弹簧启动异步异步执行任务的操作方法