【基礎篇】netty 源碼死磕1.1: html
JAVA NIO簡介編程
Java 中 New I/O類庫 是由 Java 1.4 引進的異步 IO。因爲以前老的I/O類庫是阻塞I/O,New I/O類庫的目標就是要讓Java支持非阻塞I/O,因此,更多的人喜歡稱之爲非阻塞I/O(Non-block I/O)。網絡
NIO彌補了原來同步阻塞I/O的不足,它在標準Java代碼中提供了高速的、面向塊的I/O。異步
Java NIO 由如下幾個核心部分組成:學習
Channel線程
Buffer指針
Selectornetty
舊的IO(OIO) 和 NIO 的區別主要體如今三個方面:htm
(1)OIO 基於流(Stream oriented),而 NIO 基於 Buffer (Buffer oriented);blog
(2)OIO 操做是阻塞的,而 NIO 操做是非阻塞的;
(3)OIO 沒有 selector 概念,而 NIO 有 selector 概念.
舊的IO(OIO) 是面向字節流或字符流的,在通常的OIO操做中,咱們以流式的方式順序地從一個 Stream 中讀取一個或多個字節,所以,咱們也就不能隨意改變讀取指針的位置。
而在 NIO 中,而是引入了 Channel 和 Buffer 的概念。在 NIO 中,只須要從 Channel 中讀取數據到 Buffer 中,或將數據從 Buffer 中寫入到 Channel。而且,不像OIO 那樣是順序操做,在NIO 中,咱們能夠隨意地讀取任意位置的數據.
在OIO中,Java 提供的各類 stream 流操做都是阻塞的,例如咱們調用一個 read 方法讀取一個文件的內容,那麼調用 read 的線程會被阻塞住,直到 read 操做完成。
而 NIO 的非阻塞模式容許咱們非阻塞地進行 IO 操做。 例如咱們須要從網絡中讀取數據。在 NIO 的非阻塞模式中,當咱們調用 read 方法時,若是此時有數據,則 read 讀取並返回; 若是此時沒有數據,則 read 直接返回,而不會阻塞當前線程。
NIO的非阻塞,是如何作到的呢?
使用的是通道和通道的多路複用技術。先來看通道Channel。
OIO中,一般來講,一個鏈接使用有兩個流,一個輸入流一個輸出流。經過兩個流不斷的進行輸入和輸出。
與之相對應,NIO中,一般來講,一個鏈接就是一個通道Channel表示,全部的 NIO 的 I/O 操做都是從 Channel 開始的。 一個 channel 相似於OIO中的兩個 stream的結合體。
通道Channel要進行多路複用,基礎就是選擇器selector。
Selector是何方神聖?
這是一個IO事件的查詢器,經過 Selector,一個線程能夠查詢多個 Channel 的 IO 事件的就緒狀態。
咱們要作的工做,就是將要進行狀態查詢的Channel(至關於流)註冊到選擇器Seletor中。當咱們向一個 Selector 中註冊了 Channel 後,Selector 內部的機制就能夠自動地爲咱們不斷地查詢(select) 這些註冊的 Channel 是否有已就緒的 IO 事件(例如可讀,可寫,網絡鏈接完成等)。
經過這樣的 Selector 機制,咱們就能夠很簡單地使用一個線程高效地管理多個 Channel 了。
當咱們須要與 NIO Channel 進行交互時,咱們就須要使用到 NIO Buffer,即數據從 Buffer讀取到 Channel 中,而且從 Channel 中寫入到 Buffer 中。
Buffer的使用,也是NIO非阻塞的重要的前提和基礎之一。
下面結合實例和源碼實例,開啓JAVA NIO的死磕之路。次序從Buffer,而後到Channel,最後講最複雜的 Selector多路複用器。
代碼工程: JavaNioDemo.zip
下載地址:在瘋狂創客圈QQ羣文件共享。
瘋狂創客圈 Netty 死磕系列 10多篇深度文章: 【博客園 總入口】 QQ羣:104131248