chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

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

jf_78858299 ? 來源:微觀技術 ? 作者:Tom哥 ? 2023-02-15 16:15 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

五、 SpringBoot 注解 @Async

除了硬編碼的異步編程處理方式,SpringBoot 框架還提供了 注解式 解決方案,以 方法體 為邊界,方法體內部的代碼邏輯全部按異步方式執(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 ,當對 execute 方法 調用時,通過自定義的線程池 defaultThreadPoolExecutor 異步化執(zhí)行 execute 方法

@Service
public 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 接口進行事件處理。如果將實現(xiàn) ApplicationListener 接口的 bean 注入到上下文中,則每次使用 ApplicationContext 發(fā)布 ApplicationEvent 時,都會通知該 bean。本質上,這是標準的觀察者設計模式

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

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

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

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

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

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

    }
}

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

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));

加個餐:

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

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

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

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

@Component
public class SpringConfiguration {

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

}

我們看下改造后的運行結果:

[生產端]線程:http-nio-8090-exec-1,發(fā)布事件 1
[生產端]線程:http-nio-8090-exec-1,發(fā)布事件 2
[生產端]線程:http-nio-8090-exec-1,發(fā)布事件 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 與系統(tǒng)默認的加載順序如何?會不會有沖突?

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

圖片

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

七、消息隊列

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

消息隊列異步架構的主要角色包括消息生產者、消息隊列和消息消費者。

圖片

消息生產者就是主應用程序,生產者將調用請求封裝成消息發(fā)送給消息隊列。

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

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

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

圖片

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

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

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

    關注

    88

    文章

    3689

    瀏覽量

    95196
  • 代碼
    +關注

    關注

    30

    文章

    4899

    瀏覽量

    70658
  • spring
    +關注

    關注

    0

    文章

    340

    瀏覽量

    15046
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    Spring Boot如何實現(xiàn)異步任務

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

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

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

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

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

    幾種最基本的通訊方式解釋與總結

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

    相機曝光模式有哪幾種種類?如何設置曝光模式?

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

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

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

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

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

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

    研究實現(xiàn)了一種 HDLC (High Level Data Link Contr01)協(xié)議的改進方法,該方法把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'>實現(xiàn)</b>

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

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

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

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

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

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

    三相異步電動機的幾種調速方式

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

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

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

    PLC的編程方式編程語言

    在工業(yè)自動化領域,PLC(Programmable Logic Controller,可編程邏輯控制器)因其強大的控制功能和靈活的編程方式而得到了廣泛應用。PLC的編程
    的頭像 發(fā)表于 06-27 14:08 ?1657次閱讀

    籠形異步電機常用的降壓啟動方式

    ,保護電機和電網(wǎng)。 籠形異步電機降壓啟動方式概述 籠形異步電機在啟動時,由于轉子的慣性和負載的影響,需要較大的啟動轉矩。為了減少啟動電流,通常采用以下幾種降壓啟動
    的頭像 發(fā)表于 09-03 15:18 ?4702次閱讀