异步编程的几种种实现方式(下)

五、 springboot 注解 @async除了硬编码的异步编程处理方式,springboot 框架还提供了 注解式 解决方案,以 方法体 为边界,方法体内部的代码逻辑全部按异步方式执行。
首先,使用 @enableasync 启用异步注解
@springbootapplication@enableasyncpublic class startapplication { public static void main(string[] args) { springapplication.run(startapplication.class, args); }}自定义线程池:
@configuration@slf4jpublic class threadpoolconfiguration { @bean(name = defaultthreadpoolexecutor, destroymethod = shutdown) public threadpoolexecutor systemcheckpoolexecutorservice() { return new threadpoolexecutor(3, 10, 60, timeunit.seconds, new linkedblockingqueue(10000), new threadfactorybuilder().setnameformat(default-executor-%d).build(), (r, executor) -> log.error(system pool is full! )); }}在异步处理的方法上添加注解 @async ,当对 execute 方法 调用时,通过自定义的线程池 defaultthreadpoolexecutor 异步化执行 execute 方法
@servicepublic class asyncserviceimpl implements asyncservice { @async(defaultthreadpoolexecutor) public boolean execute(integer num) { system.out.println(线程: + thread.currentthread().getname() + , 任务: + num); return true; }}用 @async 注解标记的方法,称为异步方法。在spring boot应用中使用 @async 很简单:
调用异步方法类上或者启动类加上注解 @enableasync在需要被异步调用的方法外加上 @async所使用的 @async 注解方法的类对象应该是spring容器管理的bean对象;六、spring applicationevent 事件事件机制在一些大型项目中被经常使用,spring 专门提供了一套事件机制的接口,满足了架构原则上的解耦。
applicationcontext 通过 applicationevent 类和 applicationlistener 接口进行事件处理。如果将实现 applicationlistener 接口的 bean 注入到上下文中,则每次使用 applicationcontext 发布 applicationevent 时,都会通知该 bean。本质上,这是标准的观察者设计模式。
applicationevent 是由 spring 提供的所有 event 类的基类
首先,自定义业务事件子类,继承自 applicationevent,通过泛型注入业务模型参数类。相当于 mq 的消息体。
public class orderevent extends abstractgenericevent { public orderevent(ordermodel source) { super(source); }}然后,编写事件监听器。applicationlistener 接口是由 spring 提供的事件订阅者必须实现的接口,我们需要定义一个子类,继承 applicationlistener。相当于 mq 的消费端
@componentpublic class ordereventlistener implements applicationlistener { @override public void onapplicationevent(orderevent event) { system.out.println(【ordereventlistener】监听器处理! + json.tojsonstring(event.getsource())); }}最后,发布事件,把某个事件告诉所有与这个事件相关的监听器。相当于 mq 的生产端。
ordermodel ordermodel = new ordermodel();ordermodel.setorderid((long) i);ordermodel.setbuyername(tom- + i);ordermodel.setsellername(judy- + i);ordermodel.setamount(100l);// 发布spring事件通知springutils.getapplicationcontext().publishevent(new orderevent(ordermodel));加个餐:
[消费端]线程:http-nio-8090-exec-1,消费事件 {amount:100.0,buyername:tom-1,orderid:1,sellername:judy-1}[生产端]线程:http-nio-8090-exec-1,发布事件 1[消费端]线程:http-nio-8090-exec-1,消费事件 {amount:100.0,buyername:tom-2,orderid:2,sellername:judy-2}[生产端]线程:http-nio-8090-exec-1,发布事件 2[消费端]线程:http-nio-8090-exec-1,消费事件 {amount:100.0,buyername:tom-3,orderid:3,sellername:judy-3}[生产端]线程:http-nio-8090-exec-1,发布事件 3上面是跑了个demo的运行结果,我们发现无论生产端还是消费端,使用了同一个线程 http-nio-8090-exec-1,spring 框架的事件机制默认是同步阻塞的。只是在代码规范方面做了解耦,有较好的扩展性,但底层还是采用同步调用方式。
那么问题来了,如果想实现异步调用,如何处理?
我们需要手动创建一个 simpleapplicationeventmulticaster,并设置 taskexecutor,此时所有的消费事件采用异步线程执行。
@componentpublic class springconfiguration { @bean public simpleapplicationeventmulticaster applicationeventmulticaster(@qualifier(defaultthreadpoolexecutor) threadpoolexecutor defaultthreadpoolexecutor) { simpleapplicationeventmulticaster simpleapplicationeventmulticaster = new simpleapplicationeventmulticaster(); simpleapplicationeventmulticaster.settaskexecutor(defaultthreadpoolexecutor); return simpleapplicationeventmulticaster; }}我们看下改造后的运行结果:
[生产端]线程:http-nio-8090-exec-1,发布事件 1[生产端]线程:http-nio-8090-exec-1,发布事件 2[生产端]线程:http-nio-8090-exec-1,发布事件 3[消费端]线程:default-executor-1,消费事件 {amount:100.0,buyername:tom-2,orderid:2,sellername:judy-2}[消费端]线程:default-executor-2,消费事件 {amount:100.0,buyername:tom-1,orderid:1,sellername:judy-1}[消费端]线程:default-executor-0,消费事件 {amount:100.0,buyername:tom-3,orderid:3,sellername:judy-3}simpleapplicationeventmulticaster 这个我们自己实例化的 bean 与系统默认的加载顺序如何?会不会有冲突?
查了下 spring 源码,处理逻辑在 abstractapplicationcontext#initapplicationeventmulticaster 方法中,通过 beanfactory 查找是否有自定义的 bean,如果没有,容器会自己 new 一个 simpleapplicationeventmulticaster 对象注入到容器中。
代码地址:https://github.com/aalansehaiyang/wx-project
七、消息队列异步架构是互联网系统中一种典型架构模式,与同步架构相对应。而消息队列天生就是这种异步架构,具有超高吞吐量和超低时延。
消息队列异步架构的主要角色包括消息生产者、消息队列和消息消费者。
消息生产者就是主应用程序,生产者将调用请求封装成消息发送给消息队列。
消息队列的职责就是缓冲消息,等待消费者消费。根据消费方式又分为点对点模式和发布订阅模式两种。
消息消费者,用来从消息队列中拉取、消费消息,完成业务逻辑处理。
当然市面上消息队列框架非常多,常见的有rabbitmq、kafka、rocketmq、activemq 和 pulsar 等
不同的消息队列的功能特性会略有不同,但整体架构类似,这里就不展开了。
我们只需要记住一个关键点,借助消息队列这个中间件可以高效的实现异步编程。

工信部公示《新能源汽车动力电池综合利用管理办法》,推进资源循环利用
ATA-1200B宽带放大器的简单介绍
5G商用时代核心网现状及发展趋势分析
智驾数据采集平台搭建之多传感器联合标定
小米12新机渲染图曝光
异步编程的几种种实现方式(下)
什么是链改跟区块链有什么关系
凌空做手势,轻松控制你的电子产品
埋藏式心脏复律除颤器(ICD)的基本结构与功能详解
建筑能耗监测系统的组成、功能特点及应用范围
熔断器的型号及分类
基于IntelPXA263的智能移动信息终端设计
大数据入门分享:Hive应用场景
魅族运动耳机ep51怎么样 品质优良佩戴舒适
Broadcom收购Teknovus公司,获得EPON技术
源创通信BPI-M1+ 开源硬件开发板介绍
74ls164内部结构及其应用(74ls164引脚图及功能_工作原理)
达实信创产品解决方案为广西智慧城市建设添砖加瓦
台湾精锐APEX行星减速机行业应用案例
小米10至尊纪念版与汽车相隔千里也能实时操控!