Netty學習(一)----對JDK中IO的複習

編寫目的:Netty 是一個利用 Java 的高級網絡的能力,隱藏其背後的複雜性而提供一個易於使用的 API 的客戶端/服務器框架。
是對jdk中的IO進行了很多封裝與優化,要想全盤理解基於JDK構建出來的Netty,是有必要回憶下jdk中IO的相關知識;


在thing in java I/O章節中,是以 " 對程序語言的設計者來說,創建一個好的輸入/輸出(I/O)系統是一項艱難的任務" 這樣一句話進行了開頭;

 

一:定義

 

           java的io是實現輸入和輸出的基礎,可以方便的實現數據的輸入和輸出操作。在java中把不同的輸入/輸出源(鍵盤,文件,網絡連接等)抽象表述爲“流”(stream)。通過流的形式允許java程序使用相同的方式來訪問不同的輸入/輸出源。


二:I/O分類

 

I/O模型可以從兩個維度去理解。

  1. 阻塞與非阻塞:用戶進程發起I/O操作後,根據是否需要等待I/O操作完成才能繼續運行可以分爲阻塞以及非阻塞。
    阻塞與非阻塞針對的是I/O操作的發起者用戶進程。
     
  2. 同步與異步:當用戶進程發起I/O操作後:
  • 1:將會由用戶態轉變爲內核態。
  • 2:內核進程在接收到I/O操作,完成數據拷貝後,進行I/O操作。
  • 3:操作執行完成後,需要從內核態轉變爲用戶態並且進行數據拷貝。
  • 4:如果是同步I/O操作,則將數據拷貝到用戶空間的過程中用戶線程將會阻塞。
  • 如果是異步I/O操作,內核線程直接執行數據拷貝的過程,完成拷貝後才通知用戶進程I/O操作完成,不會造成用戶線程在數據拷貝的時候阻塞。

(ps:什麼是用戶態與核心態)

 

 

三:NIO/BIO 對比

 

 

BIO:
       傳統I/O面向於‘流’ 並存在阻塞,也是B(Locking) I/O 的定義。
意味着當一個線程掉用read()或者write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。該線程在此期間不能再幹任何事情了,Java IO面向流意味着每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方。



NIO:

Java的NIO就是上面所說的非阻塞I/O,並且支持多路複用技術,也就是非阻塞多路複用I/O

 

引入了三位不同於BIO的角色,其定義依次如下:
 

  • Channel(通道):Channel是一個雙向的數據讀/寫通道,Channel可以實現讀和寫同時操作,並且同時支持阻塞和非阻塞模式,一個客戶端連接對應一個Channel,當有新的連接請求時,會向Selector中註冊一個Channel,並且會將Channel與對應的事件處理器進行綁定,事件處理器包含了該通道里面的各類事件對應的處理邏輯。

 

  • Buffer(緩存):Channel可以從Buffer中進行讀寫操作。所有數據的讀寫都經過緩存區。在NIO中,有兩種不同的緩衝區,分別是直接緩衝區和非直接緩衝區。直接緩衝區可以直接操作JVM的堆外內存,即系統內核緩存中分配的緩衝區;非直接緩衝區則只能操作JVM的堆中內存。

 

  • Selector(選擇器):Selector通過不斷輪詢註冊在其上的Channel來選擇並分發已處理就緒的事件。它可以同時輪詢監控多個Channel,當Selector發現某個Channel的數據狀態有變化時,會通過SelectorKey觸發相關事件,並由對此事件感興趣的事件處理器來執行相關邏輯,數據則從Buffer中取,執行完後再寫會Buffer,以供Channel讀取。

 

 

引入了Reactor模式
 

Reactor模式,是一種基於事件驅動的設計模式。Reactor模式的核心思想就是減少線程的等待。當遇到需要等待 IO 時,先釋放資源,而在 IO 完成時,再通過事件驅動的方式,繼續接下來的處理。從整體上減少了資源的消耗。

 

(redis的單I/O多復路與GO裏面的channel 粗略來說,三者較爲相似)

 

 

 

 

 

 

 

 

 

 

 

 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章