NIO、BIO、AIO、同步異步、阻塞非阻塞傻傻分不清楚?

2021-01-19 探險家之指路明燈

阻塞與非阻塞

阻塞和非阻塞操作是針對發起的IO請求操作後是否立刻返回一個標誌信息而不讓請求線程等待,當數據準備未完成時,請求線程的狀態:

阻塞:往往需要等待緩衝區中的數據準備好過後才處理其他的事情,否則一直等待在那裡。

非阻塞:無論數據是否準備好,都會直接返回。

阻塞IO

非阻塞IO

同步與異步

同步與異步是基於應用程式和作業系統處理IO事件所採用的方式:

同步:應用程式要直接參與IO讀寫的操作。

異步:所有的IO操作交給作業系統去處理,應用程式只需要等待通知。

異步相比較於同步帶來的直接好處就是在我們處理IO數據的時候,異步的方式我們可以把這部分等待所消耗的資源用於處理其他事務,提升我們服務自身的性能。

同步IO

異步IO

NIO與BIO的區別總結

NIOBIO基於緩衝區( Buffer )基於流( Stream )非阻塞 IO阻塞 IO選擇器( Selector )無

BIO

Blocking IO,是同步阻塞的IO模型,傳統的IO【java.io包】就是這種模型。

BIO面向字節流或字符流,以流的方式順序地處理一個或多個字節。

BIO的IO操作是阻塞式的:當一個線程調用read()或write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再幹任何事情了。

採用BIO形式的網絡通信,伺服器端啟動一個ServerSocket,客戶端需要啟動Socket來進行一對一連接,如果客戶端有多個客戶端請求,當其中一個客戶端線程連接成功後,其他的將會阻塞。如果需要實現服務端同時處理多個客戶端線程,必然需要伺服器端開啟多線程與之對應,這樣就會導致如果客戶端請求過多,伺服器線程開闢過多導致系統崩潰。

NIO

NIO是Java1.4引入的,相對於傳統的IO來說,N可以代表New的意思,表示新IO,但更為具體的理解是Non-blocking的意思,是一種同步非阻塞的IO模型。它提供了Buffer,Channel,Selector三大組件。

同步與非阻塞怎麼理解,是否矛盾?非阻塞體現在:用戶程序發起IO操作請求後不等待數據,而是調用會立即返回一個標誌信息告知條件不滿足,數據未準備好,用戶請求程序繼續執行其他任務。執行完其他任務,用戶程序會主動輪詢查看IO操作條件是否滿足,如果滿足,則用戶程序親自參與拷貝數據動作,這是同步的過程。

NIO支持面向Buffer,基於Channel的IO操作,任何數據在Buffer中進行處理,且能夠任意改變操作位置,處理靈活。

NIO的IO操作可以是非阻塞的:當一個線程執行從Channel讀取數據的IO操作時,如果有數據,則返回數據;如果沒數據,不需要阻塞,而是可以直接返回。

NIO實現非阻塞IO的其中關鍵組件之一就是Selector,可以註冊多個Channel到一個Selector中。Selector可以不斷執行select操作,判斷這些註冊的Channel是否有已就緒的IO事件,如可讀,可寫,網絡連接已完成等。一個線程通過使用一個Selector管理多個Channel。

NIO就是一個線程負責所有請求連接但不處理IO操作,該線程只負責把連接註冊到多路復用器上,多用復用器輪詢到連接有IO請求時候再啟動其它線程處理IO請求操作,實現一個線程或少量線程就可以對應眾多的客戶端線程。

AIO是啥?

JDK1.7中,java.nio.channels包下增加了多個異步通道,是NIO的升級版本,實現AIO AsynchronousIO的異步非阻塞IO模型。

非阻塞前面已經解釋過了,異步指的就是數據拷貝階段完全由作業系統處理,而應用程式只需要等待通知即可。

總結

同步與異步的區別在於數據拷貝階段是否需要完全由作業系統處理。阻塞和非阻塞操作是針對發起的IO請求操作後是否立刻返回一個標誌信息而不讓請求線程等待。BIO是同步阻塞式的IO模型,面向流操作,保證順序,如JDK1.4之前的傳統IO操作。NIO是同步非阻塞式的IO模型,面向緩衝區,提供Channel,Buffer,Selector等抽象,如JDK1.4引入的IO操作。AIO是異步非阻塞式的IO模型,如JDK1.7引入的IO操作。原文連結:https://www.cnblogs.com/summerday152/p/14223272.html

如果覺得本文對你有幫助,可以轉發關注支持一下

相關焦點

  • 通俗系列之同步、異步、阻塞和非阻塞
    前言在日常的開發中,經常出現同步、異步、阻塞和非阻塞等概念。有些人搞不清楚什麼代碼是同步,什麼代碼是異步。有些人說我用異步了啊,為什麼效率還是沒提高呢?也許你是用異步了,但是可能是異步阻塞了。有些人一聽說異步好,就不管三七二十一,所有方法全部改成異步,然後就會產生新的問題。歸根結底還是對同步、異步、阻塞和非阻塞的概念不理解。
  • NIO&AIO編程模型
    上圖是NIO的線程模型, 基於select實現, 這種線程模型的特點: 多條channel通過一個選擇器和單挑線程綁定, 並且在這種編程模型中, Channel中相關業務邏輯不允許存在耗時的任務 , 如果一定會有耗時的邏輯, 請將它們放置到線程池中去運行, 因為這種模型雖然做到了非阻塞, 但是他並不是真正的異步編程, 任何channel上的任何耗時的操作, 都會拖垮這個選擇器
  • 面試經常問的BIO,AIO,NIO,來了解下
    理解同步、異步、阻塞、非阻塞什麼是同步,什麼是異步?同步:從時間上強調處理事情的結果,強調結果意味著對結果的迫不及待,不管結果如何,反正你要立即給我一個結果響應,一直處於等待狀態。異步:調用者發起一個調用後,立刻得到被調用者的回應表示已接收到請求,但是被調用者並沒有返回結果,此時調用者在等待結果過程中浪費時間是極其難受的,這個時候我們可以處理其他的請求,被調用者通常依靠事件、回調等機制來通知調用者其返回結果。什麼是阻塞,什麼是非阻塞?阻塞:調用者發起一個請求,會一直等待請求結果返回,也就是當前線程會被掛起,沒法做其他事情。
  • 【邏輯】verilog中阻塞賦值和非阻塞賦值的區別
    而語句「x<=next_x;」中的x的值是D觸發器經過一個同步脈衝後的輸出值(Q1)。基於此這個進程產生了與阻塞賦值進程截然不同的結果,即:產生了移位寄存器的效果。簡單理解就是,阻塞賦值是按需執行,非阻塞賦值是並行執行。為了更好地理解上述要點,我們需要對Verilog 語言中的阻塞賦值和非阻塞賦值的功能和執行時間上的差別有深入的了解。
  • Django 3.1異步視圖實例學習
    在關注其代碼時候,發現其示例都是異步的寫法。可以肯定雖然這不是Django,但是肯定是類似的框架。綜合考慮,Django將目前默認同步執行的視圖改為異步還是非常有意義的。雖然等待I/O操作數微秒時,但是這會阻塞。如果換成異步就不會任何阻塞,可以同時處理其他任務,從而以較低的延遲處理更多的請求。這尤其對Facebook這樣的大型網站性能改善而言。
  • 十年架構經驗工程師,帶你讀懂IO/NIO模型
    也就是說用戶線程完全不需要實際的整個IO操作是如何進行的,只需要發起一個請求,當接收內核返回的成功信號時表示IO操作已完成,可以直接去使用數據了。也就是說在異步IO模型中,IO操作的兩個階段都不會阻塞用戶線程,這兩個階段都是由內核自動完成,然後發送一個信號告知用戶線程操作已完成。用戶線程中不需要再次調用IO函數進行具體的讀寫。
  • Java NIO 基礎知識
    非阻塞 IO相信讀者在很多地方都看到過說 NIO 其實不是代表 New IO,而是 Non-Blocking IO,我們這裡不糾結這個。我想之所以會有這個說法,是因為在 Java 1.4 第一次推出 NIO 的時候,提供了 Non-Blocking IO 的支持。在理解非阻塞 IO 前,我們首先要明白,它的對立面 阻塞模式為什麼不好。
  • 「正點原子Linux連載」第五十二章Linux阻塞和非阻塞IO實驗
    第五十二章Linux阻塞和非阻塞IO實驗阻塞和非阻塞IO是Linux驅動開發裡面很常見的兩種設備訪問模式,在編寫驅動的時候一定要考慮到阻塞和非阻塞。本章我們就來學習一下阻塞和非阻塞IO,以及如何在驅動程序中處理阻塞與非阻塞,如何在驅動程序使用等待隊列和poll機制。
  • 《Java 8 in Action》CompletableFuture:組合式異步編程
    與此相反,如果你的意圖是實現並發,而非並行,或者你的主要目標是在同一個CPU上執行幾個鬆耦合的任務,充分利用CPU的核,讓其足夠忙碌,從而最大化程序的吞吐量,那麼你其實真正想做的是避免因為等待遠程服務的返回,或者對資料庫的查詢,而阻塞線程的執行,浪費寶貴的計算資源,因為這種等待的時間很可能相當長。1.
  • JAVA高並發網絡編程之BIO堵塞網絡編程
    一個一個處理的,也只能一次處理一個,也不太符合網絡編程的需求,沒有數據會堵塞。 這個通過socket支持http的方式,其實就是一個開發網絡協議的工程,如果需要支持更多的協議,需要在tcp之上運用更多的協議,說完支持http協議,BIO這塊基本就告一段落了,發現java對於網絡的封裝還是比較友好,比較便捷的,同時要應用級別的開發,更強大的功能,直接去socket它是支持不了的
  • 聊聊java中NIO的2.0版本AIO
    它提供了很多異步的IO操作方法,比如說緩衝區ByteBuffer、Pipe、Channel還有多路復用器Selector等等。新的NIO類庫的出現,極大地促進了java對異步非阻塞式編程的發展。NIO的原理也是很簡單。在這裡同樣使用一張圖來演示一遍:現在我們可以看到,所有的客戶端連接都可以只用一個線程就可以實現了。
  • Java並發編程:如何防止在線程阻塞與喚醒時死鎖
    其次,wait與notify方法必須在synchronized塊或方法中被調用,並且要保證同步塊或方法的鎖對象與調用wait與notify方法的對象是同一個。如此一來在調用wait之前當前線程就已經成功獲取某對象的鎖,執行wait阻塞後當前線程就將之前獲取的對象鎖釋放。
  • Django 3.0 將支持異步功能
    根據 Django 的項目目錄,Django 異步功能草案(DEP 0009)已被技術委員會通過,預計將在 3.0 中正式引入。
  • 恐動脈阻塞心絞痛
    不只是心情不好!家住臺中的70歲林老太太,近10年老是出現「心痛的感覺」,以為是小兒子惹她生氣、心情不好所致,沒想到去年底突然昏倒不省人事,到醫院急診室才發現是心血管已嚴重阻塞,之前的心痛感覺竟是心絞痛的徵兆,若不儘快疏通阻塞和治療,生命堪憂。
  • 源碼解析:阻塞隊列 LinkedBlockingQueue
    因為LinkedBlockingQueue既可以在初始構造時就指定隊列的容量,也可以不指定,如果不指定,那麼它的容量大小默認為Integer.MAX_VALUE。LinkedBlockingQueue除了底層數據結構(單鍊表)與ArrayBlockingQueue不同外,另外一個特點就是:它維護了兩把鎖——takeLock和putLock。
  • 豆瓣8.4分 劉慈欣又一科幻小說《全頻帶阻塞幹擾》將改編電影
    最難的《三體》電影一直沒有拍出來,但《流浪地球》創歷史的票房也刺激了國內科幻電影,劉慈欣又一個科幻小說《全頻帶阻塞幹擾》確定要改編電影了。網絡報導,《全頻帶阻塞幹擾》電影已經通過了備案,將由北京聚合影聯文化傳媒有限公司拍攝,編劇為易常春。
  • JAVA中使用CompletableFuture進行異步編程
    CompletableFuture異步任務執行線程池,默認是把異步任務都放在ForkJoinPool中執行。在這種方式中,主線程不會被阻塞,不需要一直等到子線程完成。主線程可以並行的執行其他任務。而生產者拿到的 FutureTask 被轉型為 Future 接口,可以阻塞式獲取任務的處理結果,非阻塞式獲取任務處理狀態。