溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java多線程并行計算中如何降低接口響應(yīng)時間

發(fā)布時間:2022-01-11 13:16:53 來源:億速云 閱讀:472 作者:柒染 欄目:編程語言

Java多線程并行計算中如何降低接口響應(yīng)時間,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

所謂的高并發(fā)除了在架構(gòu)上的高屋建瓴,還得需要開發(fā)人員在具體業(yè)務(wù)開發(fā)中注重自己的每一行代碼、每一個細(xì)節(jié),面子有的同時,更重要的還是要有里子。

面對性能,我們一定要有自己的工匠精神,不可以對任何一行代碼妥協(xié)!

今天和大家分享在業(yè)務(wù)開發(fā)中如何降低接口響應(yīng)時間的一個小技巧,也是大家日常開發(fā)中比較普遍存在的一個問題,即如何提高程序的并行計算能力?

順序執(zhí)行

很多時候,我們開發(fā)一個接口時候,需要調(diào)用多個方法,然后將各個方法返回的數(shù)據(jù)一起組裝返回給前端,比如這樣的:

Java多線程并行計算中如何降低接口響應(yīng)時間

可以看到我這里調(diào)用了4個方法,每一個方法為模擬真實耗時,所以都是延遲100ms返回一個字符串:

Java多線程并行計算中如何降低接口響應(yīng)時間

可想而知,我們這個接口的響應(yīng)時間一定會超過400ms,多次執(zhí)行都會在400ms多一點:

耗時:403ms耗時:409ms耗時:406ms

這就是順序執(zhí)行,也許大家覺得很Low,但是想想自己的代碼很多時候不就是這樣子的么?

線程池+Future并行計算

順序執(zhí)行確實很慢,所以我們需要并行執(zhí)行,即同時調(diào)用這四個方法,熟悉Java多線程的都知道,每個方法單獨開啟一個線程異步去執(zhí)行就好了,等全部執(zhí)行完了拿到獨立線程執(zhí)行的結(jié)果再組裝起來就可以了。

但是每次調(diào)用都需要創(chuàng)建四個線程,線程的創(chuàng)建和銷毀都是需要開銷的,所以我們就有了池化技術(shù)。

線程池、數(shù)據(jù)庫的連接池等都是采用的池化技術(shù):預(yù)先初始生成創(chuàng)建好的線程,等需要調(diào)用的時候拿來即用,線程完成工作后回歸空閑狀態(tài),等待下一次任務(wù)的到來,這樣就避免了線程頻繁的創(chuàng)建、銷毀,提高了程序的響應(yīng)性能。

所以我們在做并行計算的時候一定要充分的利用線程池的相關(guān)技術(shù),關(guān)于線程池的技術(shù)在我的另外一篇文章單獨講到,不了解的同學(xué)可以初步了解一下,面試也是必會題之一:

Java線程池基礎(chǔ)掃盲

下面我們直接上代碼:

Java多線程并行計算中如何降低接口響應(yīng)時間

線程池+Future

多運行幾次,看輸出響應(yīng)時間:

耗時:108ms耗時:105ms耗時:105ms

效果是不是很明顯?

直接相當(dāng)于一個方法的調(diào)用耗時,實際開發(fā)中如果你的一個接口經(jīng)過壓測耗時在100ms左右(大多數(shù)正規(guī)公司對接口性能都會要求不超過100ms),那么再通過線程池+Future并行計算的方式,并可以瞬間將你的接口性能提高上去,再也不用擔(dān)心壓測不過了。

有時候測試同學(xué)告訴你接口壓測不過是不是覺得很沒面子?那是對你職業(yè)水平很大的否定~

Java8的CompletableFuture

Future是java.util.concurrent并發(fā)包中的接口類,用來表示一個線程異步執(zhí)行后的結(jié)果,有如下核心方法:

  • Future.get():阻塞調(diào)用線程,直到計算結(jié)果返回

  • Future.isDone():判斷線程是否執(zhí)行完畢

  • Future.cancel():取消當(dāng)前線程的執(zhí)行

我們可以知道的是,F(xiàn)uture.get()是阻塞調(diào)用的,要想拿到線程執(zhí)行的結(jié)果,必須是Future.get()阻塞或者while(Future.isDone())輪詢方式調(diào)用。這種方式叫“主動拉(pull)”,現(xiàn)在都流行響應(yīng)式編程,即“主動推(push)”的方式,當(dāng)線程執(zhí)行完了,你告訴我就好了。

Java8設(shè)計了CompletableFuture這樣的一個類,我們先來看看如何用CompletableFuture來開發(fā)之前的代碼:

Java多線程并行計算中如何降低接口響應(yīng)時間

CompletableFuture并行計算

這里可以看到實現(xiàn)方式和Future并沒有什么不同,但是CompletableFuture提供了很多方便的方法,比如代碼中的allOf,thenApplyAsync,可以將多個CompletableFuture組合成一個CompletableFuture,最后調(diào)用join方法阻塞拿到結(jié)果。多次調(diào)用該接口耗時如下:

耗時:110ms耗時:108ms耗時:105ms

CompletableFuture類中有很多的方法(50+)可以供大家使用,不像Future只要那么幾個方法可以使用,這也是Java自有庫對Future的一個增強。

這里只是簡單展示了CompletableFuture的一種用法,實際開發(fā)中大家需要根據(jù)不同的場景去選擇使用不同的方法,這里對API不做具體介紹了。

Guava的ListenableFuture

總是有一些牛逼的公司牛逼的人出一些牛逼的開源組件要比官方自帶的工具類要好得多,同樣,谷歌開源的Guava中的ListenableFuture接口對java自帶的Future接口做了進(jìn)一步拓展,并且提供了靜態(tài)工具類Futures。

針對上面的代碼,我們看如何使用ListenableFuture來實現(xiàn)(與之前不同的是,Guava中需要對線程池再進(jìn)行一次包裝):

Java多線程并行計算中如何降低接口響應(yīng)時間

執(zhí)行三次請求耗時:

耗時:103ms耗時:101ms耗時:103ms

看完上述內(nèi)容,你們掌握J(rèn)ava多線程并行計算中如何降低接口響應(yīng)時間的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI