国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Java異步非阻塞編程的幾種方式

開發(fā) 開發(fā)工具
一個(gè)很簡單的業(yè)務(wù)邏輯,其他后端服務(wù)提供了一個(gè)接口,我們需要通過接口調(diào)用,獲取到響應(yīng)的數(shù)據(jù)。

 

一 從一個(gè)同步的Http調(diào)用說起

一個(gè)很簡單的業(yè)務(wù)邏輯,其他后端服務(wù)提供了一個(gè)接口,我們需要通過接口調(diào)用,獲取到響應(yīng)的數(shù)據(jù)。

逆地理接口:通過經(jīng)緯度獲取這個(gè)經(jīng)緯度所在的省市區(qū)縣以及響應(yīng)的code:

  1. curl-i"http://xxx?latitude=31.08966221524924&channel=amap7a&near=false&longitude=105.13990312814713" 
  2.  
  3. {"adcode":"510722"

服務(wù)端執(zhí)行,最簡單的同步調(diào)用方式:

 

服務(wù)端響應(yīng)之前,IO會(huì)阻塞在:java.net.SocketInputStream#socketRead0 的native方法上:

 

通過jstack日志,可以發(fā)現(xiàn),此時(shí)這個(gè)Thread會(huì)一直在runable的狀態(tài):

  1. "main"#1 prio=5 os_prio=31 tid=0x00007fed0c810000 nid=0x1003 runnable [0x000070000ce14000]   java.lang.Thread.State: RUNNABLE 
  2.         at java.net.SocketInputStream.socketRead0(Native Method) 
  3.         at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) 
  4.         at java.net.SocketInputStream.read(SocketInputStream.java:171) 
  5.         at java.net.SocketInputStream.read(SocketInputStream.java:141) 
  6.         at org.apache.http.impl.conn.LoggingInputStream.read(LoggingInputStream.java:84) 
  7.         at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137) 
  8.         at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153) 
  9.         at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282) 
  10.         at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138) 
  11.         at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56) 
  12.         at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259) 
  13.         at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163) 
  14.         at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165) 
  15.         at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273) 
  16.         at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125) 
  17.         at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272) 
  18.         at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) 
  19.         at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) 
  20.         at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) 
  21.         at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) 
  22.         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) 
  23.         at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) 
  24.         at com.amap.aos.async.AsyncIO.blockingIO(AsyncIO.java:207) 
  25.                 ....... 

線程模型示例:

 

同步最大的問題是在IO等待的過程中,線程資源沒有得到充分的利用,對于大量IO場景的業(yè)務(wù)吞吐量會(huì)有一定限制。

二 JDK NIO & Future

在JDK 1.5 中,JUC提供了Future抽象:

 

 

 


 

 

當(dāng)然并不是所有的Future都是這樣實(shí)現(xiàn)的,如 io.netty.util.concurrent.AbstractFuture 就是通過線程輪詢?nèi)ァ?/p>

這樣做的好處是,主線程可以不用等待IO響應(yīng),可以去做點(diǎn)其他的,比如說再發(fā)送一個(gè)IO請求,可以等到一起返回:

  1. "main"#1 prio=5 os_prio=31 tid=0x00007fd7a500b000 nid=0xe03 waiting on condition [0x000070000a95d000]   java.lang.Thread.State: WAITING (parking) 
  2.         at sun.misc.Unsafe.park(Native Method) 
  3. - parking to wait for  <0x000000076ee2d768> (a java.util.concurrent.CountDownLatch$Sync) 
  4.         at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 
  5.         at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836) 
  6.         at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997) 
  7.         at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304) 
  8.         at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231) 
  9.         at org.asynchttpclient.netty.NettyResponseFuture.get(NettyResponseFuture.java:162) 
  10.         at com.amap.aos.async.AsyncIO.futureBlockingGet(AsyncIO.java:201) 
  11.         ..... 
  12. "AsyncHttpClient-2-1"#11 prio=5 os_prio=31 tid=0x00007fd7a7247800 nid=0x340b runnable [0x000070000ba94000]   java.lang.Thread.State: RUNNABLE 
  13.         at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method) 
  14.         at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:198) 
  15.         at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:117) 
  16.         at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) 
  17. - locked <0x000000076eb00ef0> (a io.netty.channel.nio.SelectedSelectionKeySet) 
  18. - locked <0x000000076eb00f10> (a java.util.Collections$UnmodifiableSet) 
  19. - locked <0x000000076eb00ea0> (a sun.nio.ch.KQueueSelectorImpl) 
  20.         at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) 
  21.         at io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:693) 
  22.         at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353) 
  23.         at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140) 
  24.         at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) 
  25.         at java.lang.Thread.run(Thread.java:748) 

 

主線程在等待結(jié)果返回過程中依然需要等待,沒有根本解決此問題。

三 使用Callback回調(diào)方式

第二節(jié)中,依然需要主線程等待,獲取結(jié)果,那么可不可以在主線程完成發(fā)送請求后,再也不用關(guān)心這個(gè)邏輯,去執(zhí)行其他的邏輯?那就可以使用Callback機(jī)制。

 

如此一來,主線程再也不需要關(guān)心發(fā)起IO后的業(yè)務(wù)邏輯,發(fā)送完請求后,就可以徹底去干其他事情,或者回到線程池中再供調(diào)度。如果是HttpServer,那么需要結(jié)合Servlet 3.1的異步Servlet。

 

 

 


 

 

異步Servelt參考資料

https://www.cnblogs.com/davenkin/p/async-servlet.html

使用Callback方式,從線程模型中看,發(fā)現(xiàn)線程資源已經(jīng)得到了比較充分的利用,整個(gè)過程中已經(jīng)沒有線程阻塞。

四 Callback hell

回調(diào)地獄,當(dāng)Callback的線程還需要執(zhí)行下一個(gè)IO調(diào)用的時(shí)候,這個(gè)時(shí)候進(jìn)入回調(diào)地獄模式。

典型的應(yīng)用場景如,通過經(jīng)緯度獲取行政區(qū)域adcode(逆地理接口),然后再根據(jù)獲得的adcode,獲取當(dāng)?shù)氐奶鞖庑畔?天氣接口)。

在同步的編程模型中,幾乎不會(huì)涉及到此類問題。

 

Callback方式的核心缺陷

五 JDK 1.8 CompletableFuture

那么有沒有辦法解決Callback Hell的問題?當(dāng)然有,JDK 1.8中提供了CompletableFuture,先看看它是怎么解決這個(gè)問題的。

將逆地理的Callback邏輯,封裝成一個(gè)獨(dú)立的CompletableFuture,當(dāng)異步線程回調(diào)時(shí),調(diào)用future.complete(T) ,將結(jié)果封裝。

 

將天氣執(zhí)行的Call邏輯,也封裝成為一個(gè)獨(dú)立的CompletableFuture ,完成之后,邏輯同上。

 

compose銜接,whenComplete輸出:

 

每一個(gè)IO操作,均可以封裝為獨(dú)立的CompletableFuture,從而避免回調(diào)地獄。

CompletableFuture,只有兩個(gè)屬性:

  • result:Future的執(zhí)行結(jié)果 (Either the result or boxed AltResult)。
  • stack:操作棧,用于定義這個(gè)Future接下來操作的行為 (Top of Treiber stack of dependent actions)。

weatherFuture這個(gè)方法是如何被調(diào)用的呢?

通過堆棧可以發(fā)現(xiàn),是在 reverseCodeFuture.complete(result) 的時(shí)候,并且也將獲得的adcode作為參數(shù)執(zhí)行接下來的邏輯。

 

這樣一來,就完美解決回調(diào)地獄問題,在主的邏輯中,看起來像是在同步的進(jìn)行編碼。

六 Vert.x Future

Info-Service中,大量使用的 Vert.x Future 也是類似的解決的方案,不過設(shè)計(jì)上使用Handler的概念。

 

核心執(zhí)行的邏輯差不多:

 

這當(dāng)然不是Vertx的全部,當(dāng)然這是題外話了。

七 Reactive Streams

異步編程對吞吐量以及資源有好處,但是有沒有統(tǒng)一的抽象去解決此類問題內(nèi),答案是 Reactive Streams。

核心抽象:Publisher Subscriber Processor Subscription ,整個(gè)包里面,只有這四個(gè)接口,沒有實(shí)現(xiàn)類。

 

在JDK 9里面,已經(jīng)被作為一種規(guī)范封裝到 java.util.concurrent.Flow :

 

參考資料

https://www.baeldung.com/java-9-reactive-streams

http://ypk1226.com/2019/07/01/reactive/reactive-streams/

https://www.reactivemanifesto.org/

https://projectreactor.io/learn

一個(gè)簡單的例子:

 

 

 

 

八 Reactor & Spring 5 & Spring WebFlux

Flux & Mono

 

 

 


 

 

參考資料

https://projectreactor.io/docs/core/3.1.0.M3/reference/index.html

https://speakerdeck.com/simonbasle/projectreactor-dot-io-reactor3-intro

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2021-08-02 11:13:28

人工智能機(jī)器學(xué)習(xí)技術(shù)

2021-05-07 16:19:36

異步編程Java線程

2015-07-03 10:12:04

編程同步非阻塞

2011-04-25 11:05:10

javascript

2022-09-22 10:51:32

服務(wù)端開發(fā)者異步非阻塞編程

2019-07-23 11:01:57

Python同步異步

2022-06-22 08:16:29

異步非阻塞框架

2012-02-22 21:15:41

unixIO阻塞

2016-11-28 09:08:43

java系統(tǒng)異步非阻塞

2012-10-10 10:00:27

同步異步開發(fā)Java

2024-12-02 00:57:17

非阻塞異步編程

2018-03-28 08:52:53

阻塞非阻塞I

2025-02-17 13:23:34

Python同步阻塞MySQL

2024-09-23 17:15:28

Python并發(fā)并行

2023-12-06 07:28:47

阻塞IO異步IO

2021-06-04 18:14:15

阻塞非阻塞tcp

2020-05-08 10:34:30

Spring非阻塞編程

2021-02-04 10:50:11

網(wǎng)絡(luò)安全非阻塞模Winsock編程

2021-01-10 11:21:33

JavaScript語言開發(fā)

2024-04-24 10:57:54

Golang編程
點(diǎn)贊
收藏

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

操碰在线免费| 天堂精品中文字幕在线| 成人黄色免费观看| 一区二区国产精品视频| 免费v片在线观看| 久久精品美女视频网站| www国产精品| 亚洲qvod图片区电影| 久久黄色级2电影| 成人在色线视频在线观看免费大全| 一区二区三区在线免费视频| 欧洲在线视频| 日韩美女主播视频| 日产国产高清一区二区三区| 97人人模人人爽视频一区二区| 国内不卡的一区二区三区中文字幕| 亚洲爱爱爱爱爱| 国产无遮挡裸体免费久久| 波多野结衣激情| 精品国产精品网麻豆系列| 天天躁日日躁狠狠躁欧美| 亚洲最大成人网色| 亚洲欧洲在线观看av| 最爽无遮挡行房视频在线| 精品国产乱码久久久久久108| 国产亚洲精品中文字幕| 亚洲成人久久电影| 国产mv日韩mv欧美| 男人添女人下部视频免费| zzjj国产精品一区二区| 亚洲男女自偷自拍| 99riav在线| 日韩一区二区高清| 91麻豆精品国产综合久久久 | 亚洲日韩欧美一区二区在线| 亚洲综合福利| 免费人成黄页在线观看忧物| 日韩精品久久久免费观看| 北岛玲一区二区三区四区| 黄页视频在线观看| 欧美日本国产在线| 艳妇臀荡乳欲伦亚洲一区| 黄色一区二区三区四区| 欧美大片网站| 久草在线免费福利资源| 99热这里只有精品免费| 97av在线视频| 亚洲国产毛片完整版| 久久久久久久电影| 久久成人亚洲| 国产精品一区二区三区av麻 | 亚洲国产一区二区在线| 欧美大片网站在线观看| 欧美影院在线播放| 色香蕉久久蜜桃| 日韩电影在线视频| 三级在线观看视频| 日韩欧美三级电影| 少妇高潮 亚洲精品| 亚洲韩国精品一区| 2020最新国产精品| 1024精品视频| 欧美大尺度在线观看| 精久久久久久久久久久| 好看的中文字幕在线播放| 最新欧美日韩亚洲| 国产一区二中文字幕在线看| 日韩中文字幕免费看| 色噜噜狠狠成人中文综合| 久久国产成人午夜av影院| 国产美女福利在线| 台湾av在线二三区观看| 日本精品一区二区三区在线| 日本一区二区视频在线| 成人免费无遮挡| 国产va在线观看| 91精品国产99久久久久久红楼| 欧美视频中文在线看| 老司机精品视频网站| 久久精品免视看国产成人| 亚洲欧美自拍另类日韩| 天天爱天天做天天操| 日本最新一区二区三区视频观看| 伊人亚洲福利一区二区三区| 久久久另类综合| 精品三级av| 国内精彩免费自拍视频在线观看网址| 奇米精品一区二区三区| 不卡av电影在线观看| 亚洲国模精品私拍| 91黄色免费网站| 97久久人人超碰| 豆花视频一区二区| 999精品视频在线观看| 精品成人一区二区三区免费视频| 精品国产一区二区三区无码| 成人性免费视频| 日本美女爱爱视频| 国产一区二区三区奇米久涩| 久久在线视频在线| 欧美专区在线观看| 日本一区二区三区在线播放 | 欧美jizz18性欧美| 在线看a视频| 性生大片免费观看性| 成人免费视频77777| 永久免费看av| 日韩亚洲不卡在线| 97碰在线观看| 日韩网站免费观看| 国产欧美日韩中文字幕| 国产伦一区二区三区色一情| 欧美日韩国产精品一区二区| 亚洲精品v日韩精品| 国产三级一区二区| 欧洲av一区二区嗯嗯嗯啊| 亚洲免费高清视频| 国产精品国产亚洲伊人久久| 日韩妆和欧美的一区二区| 日韩欧美xxxx| 69免费视频| 性欧美超级视频| 久久视频国产| 97国产一区二区| 亚洲国产精品一区二区久久| 国产一区二区三区四区福利| 国产精品69av| 日韩手机在线观看视频| 欧美少妇网站| 福利欧美精品在线| 成人ar影院免费观看视频| 欧美综合亚洲图片综合区| 欧美国产精品日韩| 一本—道久久a久久精品蜜桃| 色播色播色播色播色播在线| 久久中文资源| 99riav一区二区三区| 亚洲男人天堂九九视频| 成人激情视频在线播放| 国产精品无码人妻一区二区在线| www免费网站在线观看| 国产精品极品在线观看| 国产一区二区三区国产| 亚洲第一av网站| 日韩欧美视频一区二区三区四区| 日本成人网址| 综合一区在线| 在线影院国内精品| 亚洲精品欧美一区二区三区| 色播在线观看| 久久久久久久久久久妇女| 色一情一乱一乱一91av| 秋霞午夜一区二区| 中文字幕亚洲精品视频| 九色porny视频在线观看| 国产精品久久久免费| 欧美日韩免费看| 国产一区二区三区丝袜 | 亚洲国产日韩一区二区| 日韩av电影在线网| 日本成人黄色网址| 狂野欧美性猛交xxxx| 国产在线播精品第三| 中文字幕无线精品亚洲乱码一区| 熟女少妇在线视频播放| 欧美美女福利视频| 一区二区三区欧美在线观看| 国产日韩精品入口| 牛牛电影国产一区二区| 极品尤物久久久av免费看| 精品国产制服丝袜高跟| 免费观看中文字幕| 日本欧美高清| 欧美欧美欧美欧美首页| 免费成人在线观看av| 亚洲欧洲日韩精品在线| 91国偷自产一区二区开放时间 | 亚洲精品久久久久久久久| a级片一区二区| 七七成人影院| 人妖欧美一区二区| 精品国产免费久久| 国产欧美日韩视频一区二区三区| 牛牛电影国产一区二区| 日本在线播放一区二区三区| 久久久久久久国产| 呦呦在线视频| 亚洲自拍偷拍欧美| 国产69精品久久久久9999apgf| 涩涩在线视频| 你懂的视频欧美| 国产欧美日韩在线观看| 高清av免费一区中文字幕| 精品一区二区三区中文字幕| 欧美视频中文字幕| 国产免费黄色av| 国产欧美精品久久| 日韩免费观看网站| 欧美暴力调教| 亚洲成人精品久久|