色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

異步編程的幾種種實(shí)現(xiàn)方式(下)

jf_78858299 ? 來源:微觀技術(shù) ? 作者:Tom哥 ? 2023-02-15 16:15 ? 次閱讀

五、 SpringBoot 注解 @Async

除了硬編碼的異步編程處理方式,SpringBoot 框架還提供了 注解式 解決方案,以 方法體 為邊界,方法體內(nèi)部的代碼邏輯全部按異步方式執(zhí)行。

首先,使用 @EnableAsync 啟用異步注解

@SpringBootApplication
@EnableAsync
public class StartApplication {

    public static void main(String[] args) {
        SpringApplication.run(StartApplication.class, args);
    }
}

自定義線程池:

@Configuration
@Slf4j
public 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 ,當(dāng)對 execute 方法 調(diào)用時,通過自定義的線程池 defaultThreadPoolExecutor 異步化執(zhí)行 execute 方法

@Service
public class AsyncServiceImpl implements AsyncService {

    @Async("defaultThreadPoolExecutor")
    public Boolean execute(Integer num) {
        System.out.println("線程:" + Thread.currentThread().getName() + " , 任務(wù):" + num);
        return true;
    }

}

用 @Async 注解標(biāo)記的方法,稱為異步方法。在spring boot應(yīng)用中使用 @Async 很簡單:

  • 調(diào)用異步方法類上或者啟動類加上注解 @EnableAsync
  • 在需要被異步調(diào)用的方法外加上 @Async
  • 所使用的 @Async 注解方法的類對象應(yīng)該是Spring容器管理的bean對象;

六、Spring ApplicationEvent 事件

事件機(jī)制在一些大型項目中被經(jīng)常使用,Spring 專門提供了一套事件機(jī)制的接口,滿足了架構(gòu)原則上的解耦。

ApplicationContext 通過 ApplicationEvent 類和 ApplicationListener 接口進(jìn)行事件處理。如果將實(shí)現(xiàn) ApplicationListener 接口的 bean 注入到上下文中,則每次使用 ApplicationContext 發(fā)布 ApplicationEvent 時,都會通知該 bean。本質(zhì)上,這是標(biāo)準(zhǔn)的觀察者設(shè)計模式

ApplicationEvent 是由 Spring 提供的所有 Event 類的基類

首先,自定義業(yè)務(wù)事件子類,繼承自 ApplicationEvent,通過泛型注入業(yè)務(wù)模型參數(shù)類。相當(dāng)于 MQ 的消息體。

public class OrderEvent extends AbstractGenericEvent {
    public OrderEvent(OrderModel source) {
        super(source);
    }
}

然后,編寫事件監(jiān)聽器。ApplicationListener 接口是由 Spring 提供的事件訂閱者必須實(shí)現(xiàn)的接口,我們需要定義一個子類,繼承 ApplicationListener。相當(dāng)于 MQ 的消費(fèi)端

@Component
public class OrderEventListener implements ApplicationListener<OrderEvent> {
    @Override
    public void onApplicationEvent(OrderEvent event) {

        System.out.println("【OrderEventListener】監(jiān)聽器處理!" + JSON.toJSONString(event.getSource()));

    }
}

最后,發(fā)布事件,把某個事件告訴所有與這個事件相關(guān)的監(jiān)聽器。相當(dāng)于 MQ 的生產(chǎn)端。

OrderModel orderModel = new OrderModel();
orderModel.setOrderId((long) i);
orderModel.setBuyerName("Tom-" + i);
orderModel.setSellerName("judy-" + i);
orderModel.setAmount(100L);
// 發(fā)布Spring事件通知
SpringUtils.getApplicationContext().publishEvent(new OrderEvent(orderModel));

加個餐:

[消費(fèi)端]線程:http-nio-8090-exec-1,消費(fèi)事件 {"amount":100.0,"buyerName":"Tom-1","orderId":1,"sellerName":"judy-1"}
[生產(chǎn)端]線程:http-nio-8090-exec-1,發(fā)布事件 1
[消費(fèi)端]線程:http-nio-8090-exec-1,消費(fèi)事件 {"amount":100.0,"buyerName":"Tom-2","orderId":2,"sellerName":"judy-2"}
[生產(chǎn)端]線程:http-nio-8090-exec-1,發(fā)布事件 2
[消費(fèi)端]線程:http-nio-8090-exec-1,消費(fèi)事件 {"amount":100.0,"buyerName":"Tom-3","orderId":3,"sellerName":"judy-3"}
[生產(chǎn)端]線程:http-nio-8090-exec-1,發(fā)布事件 3

上面是跑了個demo的運(yùn)行結(jié)果,我們發(fā)現(xiàn)無論生產(chǎn)端還是消費(fèi)端,使用了同一個線程 http-nio-8090-exec-1,Spring 框架的事件機(jī)制默認(rèn)是同步阻塞的。只是在代碼規(guī)范方面做了解耦,有較好的擴(kuò)展性,但底層還是采用同步調(diào)用方式。

那么問題來了,如果想實(shí)現(xiàn)異步調(diào)用,如何處理?

我們需要手動創(chuàng)建一個 SimpleApplicationEventMulticaster,并設(shè)置 TaskExecutor,此時所有的消費(fèi)事件采用異步線程執(zhí)行。

@Component
public class SpringConfiguration {

    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster(@Qualifier("defaultThreadPoolExecutor") ThreadPoolExecutor defaultThreadPoolExecutor) {
        SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
        simpleApplicationEventMulticaster.setTaskExecutor(defaultThreadPoolExecutor);
        return simpleApplicationEventMulticaster;
    }

}

我們看下改造后的運(yùn)行結(jié)果:

[生產(chǎn)端]線程:http-nio-8090-exec-1,發(fā)布事件 1
[生產(chǎn)端]線程:http-nio-8090-exec-1,發(fā)布事件 2
[生產(chǎn)端]線程:http-nio-8090-exec-1,發(fā)布事件 3
[消費(fèi)端]線程:default-executor-1,消費(fèi)事件 {"amount":100.0,"buyerName":"Tom-2","orderId":2,"sellerName":"judy-2"}
[消費(fèi)端]線程:default-executor-2,消費(fèi)事件 {"amount":100.0,"buyerName":"Tom-1","orderId":1,"sellerName":"judy-1"}
[消費(fèi)端]線程:default-executor-0,消費(fèi)事件 {"amount":100.0,"buyerName":"Tom-3","orderId":3,"sellerName":"judy-3"}

SimpleApplicationEventMulticaster 這個我們自己實(shí)例化的 Bean 與系統(tǒng)默認(rèn)的加載順序如何?會不會有沖突?

查了下 Spring 源碼,處理邏輯在 AbstractApplicationContext#initApplicationEventMulticaster 方法中,通過 beanFactory 查找是否有自定義的 Bean,如果沒有,容器會自己 new 一個 SimpleApplicationEventMulticaster 對象注入到容器中。

圖片

代碼地址:https://github.com/aalansehaiyang/wx-project

七、消息隊列

異步架構(gòu)是互聯(lián)網(wǎng)系統(tǒng)中一種典型架構(gòu)模式,與同步架構(gòu)相對應(yīng)。而消息隊列天生就是這種異步架構(gòu),具有超高吞吐量和超低時延。

消息隊列異步架構(gòu)的主要角色包括消息生產(chǎn)者、消息隊列和消息消費(fèi)者。

圖片

消息生產(chǎn)者就是主應(yīng)用程序,生產(chǎn)者將調(diào)用請求封裝成消息發(fā)送給消息隊列。

消息隊列的職責(zé)就是緩沖消息,等待消費(fèi)者消費(fèi)。根據(jù)消費(fèi)方式又分為點(diǎn)對點(diǎn)模式發(fā)布訂閱模式兩種。

消息消費(fèi)者,用來從消息隊列中拉取、消費(fèi)消息,完成業(yè)務(wù)邏輯處理。

當(dāng)然市面上消息隊列框架非常多,常見的有RabbitMQ、Kafka、RocketMQ、ActiveMQ 和 Pulsar 等

圖片

不同的消息隊列的功能特性會略有不同,但整體架構(gòu)類似,這里就不展開了。

我們只需要記住一個關(guān)鍵點(diǎn),借助消息隊列這個中間件可以高效的實(shí)現(xiàn)異步編程。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3637

    瀏覽量

    93900
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4820

    瀏覽量

    68882
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    14368
收藏 人收藏

    評論

    相關(guān)推薦

    Spring Boot如何實(shí)現(xiàn)異步任務(wù)

    Spring Boot 提供了多種方式實(shí)現(xiàn)異步任務(wù),這里介紹三種主要實(shí)現(xiàn)方式。 1、基于注解 @Async @Async 注解是 Spri
    的頭像 發(fā)表于 09-30 10:32 ?1460次閱讀

    USART異步工作方式編程

    USART異步工作方式編程 串行通信的接收有查詢和中斷2種方式,在實(shí)際應(yīng)用中,一般不采用查詢接收數(shù)據(jù),常用的是中斷接收數(shù)據(jù)。發(fā)送有中斷發(fā)送和非中斷發(fā)送,在下面的例程中我們采用了中斷接收
    發(fā)表于 09-08 09:48

    【我是電子發(fā)燒友】低功耗設(shè)計的最佳編程模型:異步編程

    異步編程可以編寫出速度快、資源省的高效程序,可以在單線程環(huán)境實(shí)現(xiàn)高并發(fā),可以在沒有操作系統(tǒng)的情況實(shí)現(xiàn)
    發(fā)表于 04-29 20:30

    有哪幾種方式可以通過Keil模塊化編程實(shí)現(xiàn)流水燈設(shè)計?

    Keil的模塊化編程是什么?有哪幾種方式可以通過Keil模塊化編程實(shí)現(xiàn)流水燈設(shè)計?如何對流水燈設(shè)計進(jìn)行Proteus仿真?
    發(fā)表于 07-14 07:17

    幾種最基本的通訊方式解釋與總結(jié)

    問題的地方,麻煩各位及時反饋一,謝謝。在對幾種協(xié)議進(jìn)行介紹之前,先介紹三個基本概念:(1)異步和同步假設(shè)現(xiàn)在有兩臺設(shè)備A、B之間需要盡心通信,如果A與B兩臺設(shè)備使用的是同一個時鐘信號,則稱為同步,如果使用的不是同一個時鐘信號,
    發(fā)表于 02-23 07:30

    相機(jī)曝光模式有哪幾種種類?如何設(shè)置曝光模式?

    相機(jī)曝光模式有哪幾種種類?如何設(shè)置曝光模式?
    發(fā)表于 03-02 09:34

    Modbus通訊協(xié)議的幾種實(shí)現(xiàn)方式

    Modbus通訊的方式   針對Modbus的串口和TCP兩種不同的方式,在LabVIEW中通常可以通過以下幾種方法實(shí)現(xiàn)Modbus通訊。其中一些實(shí)
    發(fā)表于 05-05 16:19

    請問一plc可以實(shí)現(xiàn)無線通信嗎?有幾種方式

    請問一plc可以實(shí)現(xiàn)無線通信嗎?有幾種方式
    發(fā)表于 05-09 17:23

    異步傳輸方式的HDLC協(xié)議的實(shí)現(xiàn)

    研究實(shí)現(xiàn)了一種 HDLC (High Level Data Link Contr01)協(xié)議的改進(jìn)方法,該方法把HDLC協(xié)議傳統(tǒng)的同步傳榆方式改成了異步傳輸方式,既保留了原有HDLC協(xié)議
    發(fā)表于 07-20 17:25 ?62次下載
    <b class='flag-5'>異步</b>傳輸<b class='flag-5'>方式</b>的HDLC協(xié)議的<b class='flag-5'>實(shí)現(xiàn)</b>

    快速改變?yōu)V波器中心頻率的幾種實(shí)現(xiàn)方式

    快速改變?yōu)V波器中心頻率的幾種實(shí)現(xiàn)方式,下來看看
    發(fā)表于 01-07 21:24 ?12次下載

    在Python中實(shí)現(xiàn)異步編程(附源碼)

    異步編程是并行編程的一種方式。單個工作單元獨(dú)立于主應(yīng)用程序線程運(yùn)行,并通知調(diào)用線程其完成、失敗情況或進(jìn)度。下面這張圖理解起來會更直觀一些:
    的頭像 發(fā)表于 10-27 14:36 ?2375次閱讀
    在Python中<b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>異步</b><b class='flag-5'>編程</b>(附源碼)

    異步編程幾種種實(shí)現(xiàn)方式(上)

    異步編程是讓程序并發(fā)運(yùn)行的一種手段。它允許多個事件同時發(fā)生,當(dāng)程序調(diào)用需要長時間運(yùn)行的方法時,它不會阻塞當(dāng)前的執(zhí)行流程,程序可以繼續(xù)運(yùn)行。
    的頭像 發(fā)表于 02-15 16:15 ?777次閱讀
    <b class='flag-5'>異步</b><b class='flag-5'>編程</b>的<b class='flag-5'>幾種種</b><b class='flag-5'>實(shí)現(xiàn)</b><b class='flag-5'>方式</b>(上)

    三相異步電動機(jī)的幾種調(diào)速方式

    介紹了幾種調(diào)速的方式
    發(fā)表于 10-07 11:18 ?0次下載

    java實(shí)現(xiàn)多線程的幾種方式

    Java實(shí)現(xiàn)多線程的幾種方式 多線程是指程序中包含了兩個或以上的線程,每個線程都可以并行執(zhí)行不同的任務(wù)或操作。Java中的多線程可以提高程序的效率和性能,使得程序可以同時處理多個任務(wù)。 Java提供
    的頭像 發(fā)表于 03-14 16:55 ?767次閱讀

    籠形異步電機(jī)常用的降壓啟動方式

    ,保護(hù)電機(jī)和電網(wǎng)。 籠形異步電機(jī)降壓啟動方式概述 籠形異步電機(jī)在啟動時,由于轉(zhuǎn)子的慣性和負(fù)載的影響,需要較大的啟動轉(zhuǎn)矩。為了減少啟動電流,通常采用以下幾種降壓啟動
    的頭像 發(fā)表于 09-03 15:18 ?2013次閱讀
    主站蜘蛛池模板: 人人澡人人爽人人精品| 日本久久久久久久做爰片日本| 高h 纯肉文| a免费视频| 97在线视频免费播放| 男人J放进女人P全黄网站| 海量激情文学| 国产免费变态视频网址网站| 丰满女朋友在线观看中文| 99久久精品毛片免费播放| 最近中文字幕mv手机免费高清| 色偷偷超碰97人人澡人人| 青柠在线观看视频在线高清完整 | 国产成人一区二区三中文| 成年美女黄网站色app| www.青青草原| gogo免费在线观看| www.绿巨人| 被高跟鞋调教丨vk| 成人在线观看播放| 动漫美女3d被爆漫画| 国产AV无码熟妇人妻麻豆| 99久久精品6在线播放| 51精品少妇人妻AV一区二区 | 国产免国产免费| 国产这里有精品| 国产成人在线视频| 国产精品亚洲欧美| 国产学生在线播放精品视频| 动漫美女3d被爆漫画| 国产成人a v在线影院| 国产精品亚洲国产三区| 狠狠撸亚洲视频| 久久免费特黄毛片| 欧美成人免费一区二区三区不卡| 久久久久久久免费| 快乐激情站| 欧美18videosex初次| 日韩毛片大全| 亚洲AV 日韩 国产 有码| 亚洲一区在线播放|