自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

你應(yīng)該這樣去開(kāi)發(fā)接口:Java多線程并行計(jì)算

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

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

[[313379]]

 

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

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

本文主要包含以下內(nèi)容:

  1. 順序執(zhí)行很慢
  2. 線程池+Future并行計(jì)算
  3. 使用Java8的CompletableFuture
  4. 使用Guava的ListenableFuture

本文包含代碼內(nèi)容較多,大家可收藏后自己跟著動(dòng)手驗(yàn)證一番~

順序執(zhí)行

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

 

你應(yīng)該這樣去開(kāi)發(fā)接口:Java多線程并行計(jì)算

 

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

 

你應(yīng)該這樣去開(kāi)發(fā)接口:Java多線程并行計(jì)算

 

可想而知,我們這個(gè)接口的響應(yīng)時(shí)間一定會(huì)超過(guò)400ms,多次執(zhí)行都會(huì)在400ms多一點(diǎn):

耗時(shí):403ms耗時(shí):409ms耗時(shí):406ms

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

線程池+Future并行計(jì)算

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

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

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

所以我們?cè)谧霾⑿杏?jì)算的時(shí)候一定要充分的利用線程池的相關(guān)技術(shù),關(guān)于線程池的技術(shù)在我的另外一篇文章單獨(dú)講到,不了解的同學(xué)可以初步了解一下,面試也是必會(huì)題之一:

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

下面我們直接上代碼:

 

你應(yīng)該這樣去開(kāi)發(fā)接口:Java多線程并行計(jì)算

 

線程池+Future

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

耗時(shí):108ms耗時(shí):105ms耗時(shí):105ms

效果是不是很明顯?

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

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

Java8的CompletableFuture

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

  • Future.get():阻塞調(diào)用線程,直到計(jì)算結(jié)果返回
  • Future.isDone():判斷線程是否執(zhí)行完畢
  • Future.cancel():取消當(dāng)前線程的執(zhí)行

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

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

 

你應(yīng)該這樣去開(kāi)發(fā)接口:Java多線程并行計(jì)算

 

CompletableFuture并行計(jì)算

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

耗時(shí):110ms耗時(shí):108ms耗時(shí):105ms

CompletableFuture類(lèi)中有很多的方法(50+)可以供大家使用,不像Future只要那么幾個(gè)方法可以使用,這也是Java自有庫(kù)對(duì)Future的一個(gè)增強(qiáng)。

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

Guava的ListenableFuture

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

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

 

你應(yīng)該這樣去開(kāi)發(fā)接口:Java多線程并行計(jì)算

 

執(zhí)行三次請(qǐng)求耗時(shí):

耗時(shí):103ms耗時(shí):101ms耗時(shí):103ms

最后

以上就是如何讓自己的接口并行計(jì)算起來(lái)的三種實(shí)現(xiàn)方式,屬于日常開(kāi)發(fā)中比較常用的一個(gè)小技巧,這里沒(méi)有過(guò)多說(shuō)明這三種方式的具體區(qū)別,實(shí)際上還需要大家不斷的在開(kāi)發(fā)中去使用,查閱更多相關(guān)源碼和資料,只有等你真正用起來(lái)的時(shí)候,你才能有所體會(huì)!

責(zé)任編輯:華軒 來(lái)源: 今日頭條
相關(guān)推薦

2010-03-22 14:45:40

云計(jì)算

2021-06-01 05:51:37

云計(jì)算并行計(jì)算分布式計(jì)算

2023-10-30 08:57:19

.Net開(kāi)發(fā)并行計(jì)算

2009-12-18 09:38:27

.NET 4.0并行計(jì)

2011-04-20 17:15:21

并行計(jì)算

2011-04-21 09:13:14

并行計(jì)算

2012-08-17 09:32:52

Python

2021-09-09 07:16:00

C#多線程開(kāi)發(fā)

2014-04-24 10:25:15

2010-03-19 17:23:45

云計(jì)算

2019-04-18 09:15:05

DaskPython計(jì)算

2014-01-21 11:16:59

MPI并行計(jì)算

2011-05-12 11:01:26

HTML

2010-03-11 15:23:44

Visual Stud

2010-06-10 08:37:04

并行計(jì)算

2010-04-21 09:23:09

.NET 4

2017-04-24 12:07:44

Spark大數(shù)據(jù)并行計(jì)算

2011-08-29 10:40:02

浪潮英特爾并行計(jì)算

2010-04-27 17:23:34

AIX系統(tǒng)

2010-06-11 08:52:17

并行計(jì)算
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)