同步和異步、阻塞和非阻塞

1.先說結(jié)論

在討論IO的時候,同步和異步、阻塞和非阻塞是個經(jīng)久不衰的技術(shù)話題。

一個IO操作涉及兩個對象,分別是用戶進(jìn)程(線程)和系統(tǒng)內(nèi)核。

以一個IO read操作為例,經(jīng)歷兩個階段:1.等待數(shù)據(jù)準(zhǔn)備;2.將數(shù)據(jù)從內(nèi)核拷貝到用戶進(jìn)程。

各種IO模式之間的區(qū)別,要從這兩個階段去體會,重點關(guān)注用戶進(jìn)程(線程)是否讓出CPU時間片,數(shù)據(jù)拷貝是由誰來完成。下面說說個人認(rèn)同的理解:

阻塞IO和非阻塞IO,都是同步IO;都是用戶進(jìn)程(線程)從內(nèi)核中把數(shù)據(jù)取走。區(qū)別在于,阻塞IO模式下,用戶進(jìn)程會處于阻塞狀態(tài)(讓出CPU時間片),一直等待內(nèi)核把數(shù)據(jù)準(zhǔn)備好;非阻塞IO模式下,用戶進(jìn)程可以不斷地主動去看數(shù)據(jù)是否準(zhǔn)備好了,期間仍可以占用CPU時間片執(zhí)行其它指令。

異步IO是說用戶進(jìn)程(線程)發(fā)起IO請求,注冊回調(diào)接口,之后就可以執(zhí)行其它指令;由內(nèi)核負(fù)責(zé)調(diào)用回調(diào)接口把數(shù)據(jù)拷貝到用戶進(jìn)程。

2.再看概念

阻塞和非阻塞

阻塞和非阻塞,是針對用戶進(jìn)程(線程)的狀態(tài)來說的。阻塞意味著用戶進(jìn)程(線程)被掛起,即讓出CPU時間片;非阻塞意味著用戶進(jìn)程(線程)不會掛起,仍可以做其它工作。

同步和異步

同步和異步,可以認(rèn)為是針對指令執(zhí)行順序來說的。同步意味著發(fā)起調(diào)用后,沒有得到結(jié)果之前,就不返回,自然不能執(zhí)行其它指令;異步意味著調(diào)用發(fā)出后,調(diào)用方立刻返回,通過回調(diào)等措施拿到結(jié)果,這樣調(diào)用方還可以執(zhí)行其它指令。

因此,可以說阻塞和非阻塞、同步和異步,是針對不同的主體而言的。

3.Java IO

對于java程序員來說,JDK提供了bio、nio和aio,分別對應(yīng)了阻塞IO、非阻塞IO和異步IO。

以網(wǎng)絡(luò)IO的舉例來說,JDK分別提供了以下的API來實現(xiàn)不同的IO模式。

bio

  • ServerSocket
  • Socket

nio

  • ServerSocketChannel
  • SocketChannel
  • Selector

Java nio通過Selector實現(xiàn)多路復(fù)用IO,使用Reactor模式,具體到linux上,底層是epoll模式。關(guān)于select、poll和epoll的區(qū)別,此處不做討論。

aio

  • AsynchronousServerSocketChannel
  • AsynchronousSocketChannel
  • CompletionHandler

Java aio是Proactor模式,底層實現(xiàn)取決于操作系統(tǒng)是否支持異步IO,支持異步IO的linux版本,提供aio_read和aio_write函數(shù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容