当前位置: 首页 > news >正文

长春市建设厅网站/百度网页版下载安装

长春市建设厅网站,百度网页版下载安装,网站设计培训班,在下列软件中前言 在项目应用中,使用MQ异步调用来实现系统性能优化,完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部,不涉及到分布式系统,单纯的想实现部分业务的异步执行,这里介绍一个更简单的异步方法调用。 对于…

前言 

        在项目应用中,使用MQ异步调用来实现系统性能优化,完成服务间数据同步是常用的技术手段。如果是在同一台服务器内部,不涉及到分布式系统,单纯的想实现部分业务的异步执行,这里介绍一个更简单的异步方法调用。

        对于异步方法调用,从Spring3 开始提供了@Async 注解,该注解可以被标注在方法上,以便异步地调用该方法。调用者将在调用时立即返回,而方法的实际执行将提交给 Spring TaskExecutor 的任务中,由指定的线程池中的线程执行。

        本文讲述了@Async注解在Spring体系中的简单应用,仅供学习,欢迎意见反馈。  


正文

一、Spring线程池的分类

        以下是官方已经实现的常见的5个TaskExecuter。Spring 宣称对于任何场景,这些TaskExecuter完全够用了:

线程特点
SimpleAsyncTaskExecutor每次请求新开线程,没有最大线程数设置.不是真的线程池,这个类不重用线程,每次调用都会创建一个新的线程
SyncTaskExecutor不是异步的线程。同步可以用SyncTaskExecutor,但这个可以说不算一个线程池,因为还在原线程执行。这个类没有实现异步调用,只是一个同步操作。
ConcurrentTaskExecutorExecutor的适配类,不推荐使用。如果ThreadPoolTaskExecutor不满足要求时,才用考虑使用这个类。
SimpleThreadPoolTaskExecutor是Quartz的SimpleThreadPool的类。线程池同时被quartz和非quartz使用,才需要使用此类。
ThreadPoolTaskExecutor最常使用,推荐,是阿里巴巴Java开发规范中指定的线程类,要求jdk版本大于等于5。其实质是对java.util.concurrent.ThreadPoolExecutor 的包装。

       参考阿里巴巴java开发规范, 在线程池应用中:线程池不允许使用Executors去创建,也不允许使用系统默认的线程池,推荐通过 ThreadPoolExecutor 的方式,这样的处理方式让开发的工程师更加明确线程池的运行规则,规避资源耗尽的风险。

二、SpringBoot中使用@Async

        使用异步线程调用方法,过程如下:

  • 编写配置类,定义线程池
  • 启动类/配置文件上加上注解:@EnableAsync
  • 方法上加上注解:@Async

        下面演示案例中,我本地项目的目录,仅供参考:

2.1 启用@Async

        关键注解 @EnableAsync !!!可以加载启动类上,也可以加在配置文件上,效果是一样的。

  •  方式一:基于Springboot启动类启用
@EnableAsync
@SpringBootApplication
public class AsyncApplication {public static void main(String[] args) {SpringApplication.run(AsyncApplication.class, args);}}
  • 方式二:基于Java配置的启用
// com.example.async.service 为即将开启异步线程业务的包位置(后面有详细讲解)
@EnableAsync
@Configuration
@ComponentScan("com.example.async.service")
public class AsyncConfiguration implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {return executor();}...
}

2.2 @Async与线程池

        Spring应用默认的线程池,指在@Async注解在使用时,不指定线程池的名称。查看源码,@Async的默认线程池为SimpleAsyncTaskExecutor

@Slf4j
@Service
public class BusinessServiceImpl implements BusinessService {/*** 方法4:没有指定线程池,验证默认线程池也ok(不推荐:规避资源耗尽的风险)*/@Asyncpublic void asyncDemo4() {log.info("asyncDemo4:" + Thread.currentThread().getName() + " 正在执行 ----------");try {Thread.sleep(2*1000);} catch (InterruptedException e) {e.printStackTrace();}log.info("asyncDemo4:" + Thread.currentThread().getName() + " 执行结束!!");}
}

2.3 @Async自定义线程池

        自定义线程池,可对系统中线程池更加细粒度的控制,方便调整线程池大小配置,线程执行异常控制和处理。在设置系统自定义线程池代替默认线程池时,虽可通过多种模式设置,但替换默认线程池最终产生的线程池有且只能设置一个(不能设置多个类继承AsyncConfigurer)。

        自定义线程池有如下模式:

  1. 重新实现接口AsyncConfigurer;
  2. 继承AsyncConfigurerSupport;
  3. 配置由自定义的TaskExecutor替代内置的任务执行器;

        三者使用方式大体相同,下面的案例将展示说明其一:实现接口AsyncConfigurer接口的方式。

  • 配置一个线程池 ThreadPoolTaskExecutor
/*** com.example.async.service:即将开启异步线程的业务方法是哪个** 解释:*  1.即将开启异步线程业务的包位置:com.example.async.service*  2.通过 ThreadPoolExecutor 的方式,规避资源耗尽的风险*/
@EnableAsync
@Configuration
@ComponentScan("com.example.async.service")
public class AsyncConfiguration implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {return executor();}/*** 执行需要依赖线程池,这里就来配置一个线程池* 1.当池子大小小于corePoolSize,就新建线程,并处理请求* 2.当池子大小等于corePoolSize,把请求放入workQueue(QueueCapacity)中,池子里的空闲线程就去workQueue中取任务并处理* 3.当workQueue放不下任务时,就新建线程入池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理* 4.当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁*/@Bean("asyncExecutor")public ThreadPoolTaskExecutor executor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//设置线程名executor.setThreadNamePrefix("async-method-execute-");//设置核心线程数executor.setCorePoolSize(10);//设置最大线程数executor.setMaxPoolSize(50);//线程池所使用的缓冲队列executor.setQueueCapacity(100);//设置多余线程等待的时间,单位:秒executor.setKeepAliveSeconds(10);// 初始化线程executor.initialize();return executor;}
}
  • 执行异步线程方法,指定线程池:value 要与配置类 Bean() 中的name相同 
/*** 异步线程 - 执行业务* 注意:*  1.@Async 注解调用用线程池,不指定的话默认:SimpleAsyncTaskExecutor*  2.SimpleAsyncTaskExecutor 不是真的线程池,这个类不重用线程,默认每次调用都会创建一个新的线程*/
@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {/*** 方法1:@Async 标注为异步任务:执行此方法的时候,会单独开启线程来执行,不影响主线程的执行*/@Async("asyncExecutor")public void asyncDemo1() {log.info("asyncDemo1:" + Thread.currentThread().getName() + " 正在执行 ----------");// 故意等10秒,那么异步线程开起来,这样明显看到:方法2不用等方法1执行完就调用了try {Thread.sleep(10*1000);} catch (InterruptedException e) {e.printStackTrace();}log.info("asyncDemo1:" + Thread.currentThread().getName() + " 执行结束!!");}/*** 方法2:与方法1一起执行,证明2个线程异步执行,互不干扰*/@Async("asyncExecutor")public void asyncDemo2() {log.info("asyncDemo2:" + Thread.currentThread().getName() + " 正在执行 ----------");try {Thread.sleep(5*1000);} catch (InterruptedException e) {e.printStackTrace();}log.info("asyncDemo2:" + Thread.currentThread().getName() + " 执行结束!!");}/*** 方法3:没有指定线程池,验证默认线程池也ok(不推荐:规避资源耗尽的风险)*/@Asyncpublic void asyncDemo3() {log.info("asyncDemo3:" + Thread.currentThread().getName() + " 正在执行 ----------");try {Thread.sleep(1*1000);} catch (InterruptedException e) {e.printStackTrace();}log.info("asyncDemo3:" + Thread.currentThread().getName() + " 执行结束!!");}
}

2.4 启动测试

        通过 AsyncApplication 启动 SpringBoot 项目,Postman 进行接口测试:

http://127.0.0.1:8080/async/demo

  • 我写了4个demo,分别模拟4种情况,详情在注释里有写。
@Slf4j
@RestController
@RequestMapping("/async")
public class AsyncControllor {@Autowiredprivate AsyncService asyncMethodService;@Autowiredprivate BusinessService businessService;@GetMapping("/demo")public String demo()  {log.info("接口调用:【开始】 --------------------");try {// 执行异步任务 - 自定义线程池asyncMethodService.asyncDemo1();asyncMethodService.asyncDemo2();asyncMethodService.asyncDemo3();// 执行异步任务 - 默认线程池businessService.asyncDemo4();} catch (Exception e) {return "Exception";}log.info("接口调用:【结束】 --------------------");return "success";}
}
  • 运行结果:接口执行结束,异步线程仍在运行


总结

  1. @EnableAsync 是启动 @Async 异步线程的关键,可以加载启动类上,也可以加在配置文件上;
  2. 为了规避资源耗尽的风险,推荐通过 ThreadPoolExecutor 的方式创建线程池;
  3. @Async 注解标注在方法上,以便异步地调用该方法;

http://www.jmfq.cn/news/5067487.html

相关文章:

  • 网站首页倒计时功能怎么做/网站开发的步骤
  • 下沙做网站的公司/爱站工具包的主要功能
  • wordpress后台添加一级菜单/深圳优化公司找高粱seo服务
  • 一流的五屏网站建设/浙江seo推广
  • 广州市人民政府网站/百度seo发帖推广
  • 做系统前怎么保存网站上的收藏/最新军事头条
  • 做网站用的腾讯云服务器/国际军事新闻今日头条
  • 广州市天河区住房和建设局网站/seo是什么意思怎么解决
  • 个人网站做论坛/爱奇艺科技有限公司
  • 手机网站菜单网页怎么做/网站开发语言
  • 怎么样新建一个网站/免费产品推广软件
  • 网站的中英文翻译是怎么做的/360点睛实效平台推广
  • 怎样做党史网站/网站服务器
  • 设置网站/超级软文网
  • 东莞网站建设模板报价/电脑系统优化软件十大排名
  • 学校网站建设哪家好/北京网站seowyhseo
  • 高职院校高水平专业建设网站/播放量自助下单平台
  • 专业的建站/360推广登陆入口
  • 能源网站模板/seo的中文意思是什么
  • 网站开发语言总结/鲜花网络营销推广方案
  • 跨境电商网站建设主管岗位职责/搜索引擎推广
  • 怎样网站设计/系统优化大师免费版
  • 海口网站开发/网络营销策略理论有哪些
  • 做静态网站用什么软件/知乎推广优化
  • 北京定制网站开发公司/shopify seo
  • 陕西政府网站建设指引/google搜索免费入口
  • 深圳最新新闻事件/龙斗seo博客
  • 帮别人做彩票网站吗/查网站权重
  • 学习网站开发教程/网站seo综合查询
  • 网站右侧广告代码/成人职业培训机构