日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

SpringBoot 并發編程學習歷程,你所需要的所有知識點!

來源: 責編: 時間:2023-09-28 10:07:53 317觀看
導讀本教程大概目錄:模擬單線程情節用Callable實現 并發編程用DeferedResult實現異步處理###模擬單線程情節。/** * Created by Fant.J. */@RestController@Slf4jpublic class AsyncController { /** * 單線程測試

rLx28資訊網——每日最新資訊28at.com

本教程大概目錄:rLx28資訊網——每日最新資訊28at.com

  • 模擬單線程情節
  • 用Callable實現 并發編程
  • 用DeferedResult實現異步處理

###模擬單線程情節。rLx28資訊網——每日最新資訊28at.com

/** * Created by Fant.J. */@RestController@Slf4jpublic class AsyncController {    /**     * 單線程測試     * @return     * @throws InterruptedException     */    @RequestMapping("/order")    public String order() throws InterruptedException {        log.info("主線程開始");        Thread.sleep(1000);        log.info("主線程返回");        return "success";    }}

我們把線程休息一秒當作模擬處理業務所花費的時間。很明顯能看出來,這是個單線程。rLx28資訊網——每日最新資訊28at.com

rLx28資訊網——每日最新資訊28at.com

nio-8080-exec-1表示主線程的線程1。rLx28資訊網——每日最新資訊28at.com

rLx28資訊網——每日最新資訊28at.com

用Callable實現 并發編程

/**     * 用Callable實現異步     * @return     * @throws InterruptedException     */    @RequestMapping("/orderAsync")    public Callable orderAsync() throws InterruptedException {        log.info("主線程開始");        Callable result = new Callable() {            @Override            public Object call() throws Exception {                log.info("副線程開始");                Thread.sleep(1000);                log.info("副線程返回");                return "success";            }        };        log.info("主線程返回");        return result;    }

rLx28資訊網——每日最新資訊28at.com

rLx28資訊網——每日最新資訊28at.com

我們可以看到,主線程的開始和返回(結束處理)是首先執行的,然后副線程才執行真正的業務處理。說明主線程在這里的作用是調用(喚醒)子線程,子線程處理完會返回一個Object對象,然后返回給用戶。rLx28資訊網——每日最新資訊28at.com

這樣雖然實現了并發處理,但是有一個問題,就是主線程和副線程沒有做到完全分離,畢竟是一個嵌套進去的副線程。rLx28資訊網——每日最新資訊28at.com

所以為了優化我們的實現,我在這里模擬 消息中間件 來實現主線程副線程的完全分離。rLx28資訊網——每日最新資訊28at.com

用DeferedResult實現異步處理

因為本章主要講的是并發編程原理,所以這里我們不用現成的消息隊列來搞,我們模擬一個消息隊列來處理。rLx28資訊網——每日最新資訊28at.com

MockQueue .java

/** * 模擬消息隊列 類 * Created by Fant.J. */@Component@Slf4jpublic class MockQueue {    //下單消息    private String placeOrder;    //訂單完成消息    private String completeOrder;    public String getPlaceOrder() {        return placeOrder;    }    public void setPlaceOrder(String placeOrder) throws InterruptedException {        new Thread(()->{            log.info("接到下單請求"+placeOrder);            //模擬處理            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            //給completeOrder賦值            this.completeOrder = placeOrder;            log.info("下單請求處理完畢"+placeOrder);        }).start();    }    public String getCompleteOrder() {        return completeOrder;    }    public void setCompleteOrder(String completeOrder) {        this.completeOrder = completeOrder;    }}

注意再setPlaceOrder(String placeOrder)方法里,我創建了一個新的線程來處理接單的操作(為什么要建立新線程,怕主線程在這掛起,此段邏輯也沒有線程安全問題,況且異步處理更快)。傳進來的參數是個 訂單號 ,經過1s的處理成功后,把訂單號傳給completeOrder 字段,說明用戶下單成功,我在下面付controller調用該方法的代碼。rLx28資訊網——每日最新資訊28at.com

//注入模擬消息隊列類    @Autowired    private MockQueue mockQueue;    @Autowired    private DeferredResultHolder deferredResultHolder;    ....    @RequestMapping("/orderMockQueue")    public DeferredResult orderQueue() throws InterruptedException {        log.info("主線程開始");        //隨機生成8位數        String orderNumber = RandomStringUtils.randomNumeric(8);        mockQueue.setPlaceOrder(orderNumber);        DeferredResult result = new DeferredResult();        deferredResultHolder.getMap().put(orderNumber,result);        Thread.sleep(1000);        log.info("主線程返回");        return result;    }

好了,然后我們還需要一個中介類來存放訂單號和處理結果。為什么需要這么一個類呢,因為我們之前說過要實現主線程和副線程分離,所以需要一個中介來存放處理信息(比如:這個訂單號信息,和處理結果信息),我們判斷處理結果是否為空就知道該副線程執行了沒有。所以我們寫一個中介類DeferredResultHolder 。rLx28資訊網——每日最新資訊28at.com

######DeferredResultHolder .java:rLx28資訊網——每日最新資訊28at.com

/** *  訂單處理情況 中介/持有者 * Created by Fant.J. */@Componentpublic class DeferredResultHolder {    /**     * String: 訂單號     * DeferredResult:處理結果     */    private Map<String,DeferredResult> map = new HashMap<>();    public Map<String, DeferredResult> getMap() {        return map;    }    public void setMap(Map<String, DeferredResult> map) {        this.map = map;    }}

在重復一次-.-,為什么需要這么一個類呢,因為我們之前說過要實現主線程和副線程分離,所以需要一個中介來存放處理信息(比如:這個訂單號信息,和處理結果信息),一個訂單肯定要對應一個結果。不然豈不是亂了套。rLx28資訊網——每日最新資訊28at.com

DeferredResult是用來放處理結果的對象。rLx28資訊網——每日最新資訊28at.com

好了,那新問題又來了,我們怎么去判斷訂單處理成功了沒有,我們此時就需要寫一個監聽器,過100毫秒監聽一次MockQueue類中的completeOrder中是否有值,如果有值,那么這個訂單就需要被處理。我們寫一個監聽器。rLx28資訊網——每日最新資訊28at.com

######QueueListener .java:rLx28資訊網——每日最新資訊28at.com

/** * Queue監聽器 * Created by Fant.J. */@Component@Slf4jpublic class QueueListener implements ApplicationListener<ContextRefreshedEvent>{    @Autowired    private MockQueue mockQueue;    @Autowired    private DeferredResultHolder deferredResultHolder;    @Override    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {        new Thread(()->{            while(true){                //判斷CompleteOrder字段是否是空                if (StringUtils.isNotBlank(mockQueue.getCompleteOrder())){                    String orderNumber = mockQueue.getCompleteOrder();                    deferredResultHolder.getMap().get(orderNumber).setResult("place order success");                    log.info("返回訂單處理結果");                    //將CompleteOrder設為空,表示處理成功                    mockQueue.setCompleteOrder(null);                }else {                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }).start();    }}

rLx28資訊網——每日最新資訊28at.com

我們可以看到一共有三個不同的線程來處理。rLx28資訊網——每日最新資訊28at.com

rLx28資訊網——每日最新資訊28at.com

分割線后,我再給大家帶來一批干貨,自定義線程池https://www.jianshu.com/p/832f2b162450。rLx28資訊網——每日最新資訊28at.com

學完這個后,再看下面的。rLx28資訊網——每日最新資訊28at.com

我們前面的代碼中,有兩部分有用new Thread()來創建線程,我們有自己的線程池后,就可以用線程池來分配線程任務了,我在自定義線程里有講,我用的是第二種配置方法(用@Async注解來給線程 )。
修改如下:rLx28資訊網——每日最新資訊28at.com

@Async    public void setPlaceOrder(String placeOrder) throws InterruptedException {            log.info("接到下單請求"+placeOrder);            //模擬處理            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            //給completeOrder賦值            this.completeOrder = placeOrder;            log.info("下單請求處理完畢"+placeOrder);    }

我們看看效果:rLx28資訊網——每日最新資訊28at.com

rLx28資訊網——每日最新資訊28at.com

圈紅圈的就是我們自己定義的線程池里分配的線程。rLx28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-11844-0.htmlSpringBoot 并發編程學習歷程,你所需要的所有知識點!

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Elasticsearch安裝與配置指南:快速搭建高性能搜索引擎!

下一篇: 如何使用Python中的OCR技術將圖像中的文本提取為可編輯文件?

標簽:
  • 熱門焦點
  • 十個簡單但很有用的Python裝飾器

    裝飾器(Decorators)是Python中一種強大而靈活的功能,用于修改或增強函數或類的行為。裝飾器本質上是一個函數,它接受另一個函數或類作為參數,并返回一個新的函數或類。它們通常用
  • 在線圖片編輯器,支持PSD解析、AI摳圖等

    自從我上次分享一個人開發仿造稿定設計的圖片編輯器到現在,不知不覺已過去一年時間了,期間我經歷了裁員失業、面試找工作碰壁,寒冬下一直沒有很好地履行計劃.....這些就放在日
  • 雅柏威士忌多款單品價格大跌,泥煤頂流也不香了?

    來源 | 烈酒商業觀察編 | 肖海林今年以來,威士忌市場開始出現了降溫跡象,越來越多不斷暴漲的網紅威士忌也開始悄然回歸市場理性。近日,LVMH集團旗下蘇格蘭威士忌品牌雅柏(Ardbeg
  • 騰訊蓋樓,字節拆墻

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之&ldquo;想重溫暴刷深淵、30+技能搭配暴搓到爽的游戲體驗嗎?一起上晶核,即刻暴打!&rdquo;曾憑借直播騰訊旗下代理格斗游戲《DNF》一
  • 網紅炒股不為了賺錢,那就是耍流氓!

    來源:首席商業評論6月26日高調宣布入市,網絡名嘴大v胡錫進居然進軍了股市。在一次財經媒體峰會上,幾個財經圈媒體大佬就&ldquo;胡錫進炒股是否知道認真報道&rdquo;展開討論。有
  • 華為Mate 60系列用上可變靈動島:正式版體驗將會更出色

    這段時間以來,關于華為新旗艦的爆料日漸密集。據此前多方爆料,今年華為將開始恢復一年雙旗艦戰略,除上半年推出的P60系列外,往年下半年的Mate系列也將
  • 華為HarmonyOS 4.0將于8月4日發布 或搭載AI大模型技術

    華為宣布HarmonyOS4.0將于8月4日正式發布。此前,華為已經針對開發者公布了HarmonyOS4.0,以便于開發者提前進行適配,也因此被曝光出了一些新系統的特性
  • Counterpoint :OPPO雙旗艦戰略全面落地 高端產品銷量增長22%

    2023年6月30日,全球行業分析機構Counterpoint Research發布的《中國智能手機高端市場白皮書》顯示,中國智能手機品牌正在尋求高質量發展,中國高端智能
  • “買真退假” 這種“羊毛”不能薅

    □ 法治日報 記者 王春   □ 本報通訊員 胡佳麗  2020年初,還在上大學的小東加入了一個大學生兼職QQ群。群主&ldquo;七王&rdquo;在群里介紹一些刷單賺
Top 主站蜘蛛池模板: 如皋市| 奉化市| 勐海县| 益阳市| 瓦房店市| 樟树市| 长海县| 苏州市| 和平区| 澄迈县| 晋中市| 新余市| 巧家县| 景东| 红安县| 昭通市| 广平县| 淮安市| 会昌县| 仁怀市| 靖远县| 杨浦区| 克山县| 九江市| 漠河县| 满洲里市| 彰化县| 叶城县| 错那县| 内乡县| 长宁区| 个旧市| 罗田县| 娄烦县| 凯里市| 东丰县| 蓝田县| 徐汇区| 饶平县| 英超| 涿鹿县|