1. 程式人生 > 其它 >關於 BIO & NIO & AIO

關於 BIO & NIO & AIO

必要的基礎

  • IO:輸入輸出(IO)是指計算機同任何外部裝置之間的資料傳遞。

  • 同步與非同步

    • 同步: 同步就是發起一個呼叫後,被呼叫者未處理完請求之前,呼叫不返回
    • 非同步: 非同步就是發起一個呼叫後,立刻得到被呼叫者的迴應表示已接收到請求,但是被呼叫者並沒有返回結果,此時我們可以處理其他的請求,被呼叫者通常依靠事件,回撥等機制來通知呼叫者其返回結果
    • 同步非同步指的是,當資料已經ready的時候,讀寫操作是同步讀還是非同步讀
  • 阻塞與非阻塞

    • 阻塞:阻塞就是發起一個請求,呼叫者一直等待請求結果返回,也就是當前執行緒會被掛起,無法從事其他任務,只有當條件就緒才能繼續。

    • 非阻塞:非阻塞就是發起一個請求,呼叫者不用一直等著結果返回,可以先去幹其他事情。

    • 阻塞與非阻塞指的的是當不能進行讀寫(網絡卡滿時的寫/網絡卡空的時候的讀)的時候,I/O 操作立即返回還是阻塞;

  • 同/非同步 和 阻塞/非阻塞 關係

    • 阻塞與非阻塞指的的是當不能進行讀寫(網絡卡滿時的寫/網絡卡空的時候的讀)的時候,I/O 操作立即返回還是阻塞;同步非同步指的是,當資料已經ready的時候,讀寫操作是同步讀還是非同步讀,階段不同而已。美團技術團隊

那麼同步阻塞(BIO)、同步非阻塞(NIO)和非同步非阻塞(AIO)又代表什麼意思呢?上面的太抽象了

舉個生活中簡單的例子,你媽媽讓你燒水,小時候你比較笨啊,在哪裡傻等著水開(同步阻塞)。等你稍微再長大一點,你知道每次燒水的空隙可以去幹點其他事,然後只需要時不時(輪詢)來看看水開了沒有(同步非阻塞

)。後來,你們家用上了水開了會發出聲音的壺,這樣你就只需要聽到響聲後就知道水開了,在這期間你可以隨便幹自己的事情,你需要去倒水了(非同步非阻塞)。

0、BIO同步阻塞


BIO模型本質上是一對一的通訊,也就是從客戶端發起請求開始,服務端處理請求(如果資源沒有準備好,請求執行緒會一直佔用,直至請求到資源為止,這個過程中其它請求是無法被處理的),當然服務端可以通過多執行緒的方式,實現同時處理多個請求執行緒,但是多執行緒的使用要注意,因為執行緒的建立和管理非常消耗系統資源。所以這種方式對於高併發也是扛不住的。

​ 後來通過執行緒池+訊息佇列的方式,演化出偽非同步IO,服務端維護這個執行緒池和訊息佇列,如果有新的請求,服務端將其打包為一個task物件(該TasK類實現Runnable介面),將此task放入執行緒池中處理,通過訊息佇列的方式確定處理哪一個task,這種偽非同步IO

採用執行緒池實現,避免建立多個執行緒導致資源耗盡的問題,但是由於底層還是BIO模型,所以還沒有從根本解決問題。

1、NIO同步非阻塞


​ NIO在JDK1.4引入,位於JDK的java.nio包中,NIO主要涉及三個概念:Buffer緩衝區Selector選擇器Channel通道

NIO的特點如下

  • 一個執行緒可以處理多個請求

  • NIO提供非阻塞通訊方式,BIO是阻塞的

  • NIO是面向緩衝區的,BIO是面向流的

    • java中提供很多緩衝區,如ByteBuffer常用、CharBuffer、...注意StringBuffer不是Buffer緩衝區,它只是一個可以原地動態修改的String型別
    • NIO中的通訊時全雙工的,也就是可以同時讀寫操作;而BIO的流中讀寫是單向的。
  • 避免同步IO通訊效率過低

  • 減小執行緒多的壓力

    ​ 從圖中我們可以發現,客戶端和服務端可以同時使用NIO模型。

    NIO固然好,但是NIO的程式設計難度較大,維護成本較高。所以我們可以使用NIO的框架來降低開發難度,流行基於Java NIO通訊框架有Mina、Netty、Grizzly等

2、AIO非同步非阻塞


​ AIO也是基於NIO的,不過AIO是非同步非阻塞的。非同步 IO 是基於事件和回撥機制實現的,也就是應用操作之後會直接返回,不會堵塞在那裡,當後臺處理完成,作業系統會通知相應的執行緒進行後續的操作。

參考文章