這麼說吧,NIO很簡單,其實就是個牛逼IO

我是風月連城,喜歡用簡單的語言闡述知識點java

長期分享原創java文章,分享進階架構師學習筆記及學習資料編程

喜歡的能夠點贊關注,共同窗習,一塊兒進步數組



0 ) 哈哈,其實我是個標題黨,NIO不是牛逼IO,是非阻塞IO網絡

NIO 也能算是一種思想,非阻塞IO通訊思想,Netty就是基於NIO思想的NIO框架,多線程

想花一分鐘知道Netty是什麼的能夠看看這麼說吧,Netty很簡單,其實就是個Jar包,是做爲通信組件用的架構

什麼是非阻塞?(爲何我沒有說什麼是IO,既然你都學到NIO了,,,要是不知道什麼是IO的話我也沒辦法咯..)框架

這篇文章也是簡單介紹NIO,想要看各種源碼的同窗能夠繞道了- -
異步


1 ) 異步非阻塞例子:(網上看到的比較短小精悍的好例子,直接拿過來了)socket

老張愛喝茶,廢話不說,煮開水。函數

出場人物:老張,水壺兩把(普通水壺,簡稱水壺;會響的水壺,簡稱響水壺)。

1 老張把水壺放到火上,原地不動等水開。(同步阻塞)

---------->老張以爲本身有點傻

2 老張把水壺放到火上,去客廳看毛騙,時不時去看看水開沒有。(同步非阻塞)

---------->老張以爲本身有點傻

因而變高端了,買了把會響笛的那種水壺。水開以後,能大聲發出嘀~~~~的響聲。

3 老張把響水壺放到火上,立等水開。(異步阻塞)

--------->老張以爲本身有點傻

4 老張把響水壺放到火上,去客廳看毛騙,水壺響以前再也不去看它,響了再去拿壺。(異步非阻塞)

---------->嗯,老張以爲本身棒棒噠


2 ) 小結:簡單講,Java NIO的非阻塞模式就是,使一個線程從某通道發送請求讀取(或者寫入)數據,(如燒水)

他不是保持線程阻塞,因此在讀取(或者寫入)數據前,該線程能夠繼續作其餘的事情。 (例如客廳看毛騙)


3 ) IO VS NIO 的比較 (不一樣之處)

1.IO只能實現阻塞式的網絡通訊。NIO可以實現非阻塞的網絡通訊.(廢話)

2.標準IO基於字節/字符流進行操做;而NIO是基於通道(Channel)進行操做的。(話說,通往女人心靈的通道是xxx道...)

3.流的讀寫一般是單向的,要麼輸入,要麼輸出,不能既是輸入流又是輸出流。通道是雙向的,既能夠寫數據到通道,又能夠從通道中讀取數據;


4 ) 學習目標 : 雖然如今咱們不會直接編寫NIO來完成咱們的網絡層通信,而是使用成熟的基於NIO的網絡框架來實現咱們的網絡層。如,netty、mina。但對NIO網絡編程過程的瞭解,很是有助於咱們更深刻的理解netty、mina等網絡框架,以致於能更好的使用它們。有人問了,不學這個對我敲代碼有何影響,能夠說,毛影響都沒.


5 ) 知道什麼是NIO後,咱們再來看看java NIO的三個重要組成部分:

Channel(通道),Buffer(緩衝區),Selector(選擇器)。

固然,類比學習是比較好的學習方法,這裏我仍然跟傳統IO作比較,但願他不要打我


6 ) Channel ( 通道 ),顧名思義,就是通向什麼的道路,爲某個提供了渠道。

1.傳統IO中,Stream是單向的,好比InputStream只能進行讀取操做,OutputStream只能進行寫操做。

而Channel是雙向的,既可用來進行讀操做,又可用來進行寫操做。

2.具體的常見實現通道有FileChannel,SocketChanel,ServerSocketChannel,DatagramChannel等

跟具體的實現流FileInputStream,FileOutputStream,FileReader,FileWriter,節點流包裝流緩衝流等等功能相似


7 ) Buffer(緩衝區),是NIO中很是重要的一個東西,實際上就是一個容器,是一個連續數組。在NIO中全部數據的讀和寫都離不開Buffer。在NIO中,讀取的數據只能放在Buffer中。一樣地,寫入數據也是先寫入到Buffer中。


上面的圖描述了從一個客戶端向服務端發送數據,而後服務端接收數據的過程。

簡單的講就是,要想使用Channel(通道)傳遞數據,必須先把數據丟進Buffer(緩衝區,容器)裏.


在NIO中,Buffer是一個頂層父類,它是一個抽象類,經常使用的Buffer的子類有:

ByteBuffer,IntBuffer,CharBuffer,LongBuffer,DoubleBuffer,FloatBuffer,ShortBuffer等


8 ) Selector , 能夠說它是NIO中最關鍵的一個部分,Selector的做用就是用來輪詢每一個註冊的Channel,一旦發現Channel有註冊的事件發生,便獲取事件而後進行處理。

之前傳統socket編程時,accept方法會一直阻塞,直到有客戶端請求的到來,並返回socket進行相應的處理。整個過程是就像上面的例子那樣,直到水壺燒開了(響應回去了)才能去處理下一個請求.固然咱們也能夠用線程池的模式.

NIO則爲咱們提供了更好的解決方案,Selector選擇器可以檢測多個註冊的通道上是否有事件發生,若是有事件發生,便獲取事件而後針對每一個事件進行相應的響應處理。這樣一來,只是用一個單線程就能夠管理多個通道,也就是管理多個鏈接。這樣使得只有在鏈接真正有讀寫事件發生時,纔會調用函數來進行讀寫,就大大地減小了系統開銷,而且沒必要爲每一個鏈接都建立一個線程,不用去維護多個線程,而且避免了多線程之間的上下文切換致使的開銷。而且是按順序處理,基於通道(Channel)和緩衝區(Buffer)來傳輸和保存數據。

與Selector有關的一個關鍵類是SelectionKey,一個SelectionKey表示一個到達的事件,這2個類構成了服務端處理業務的關鍵邏輯。

相關文章
相關標籤/搜索