Java NIO系列2:NIO概述

rhwayfunn發表於2016-04-18

基於NIO的IO與之前的BIO有所不同,NIO的核心部分主要由三個類組成:ChannelSelectorBuffer

三者的之間的關係可以這樣理解:現在假設有兩個程式需要通訊,進行A首先將資料傳到程式A所在的緩衝區(位於作業系統使用者空間的緩衝區),然後緩衝區將資料釋放到通道中,資料流經通道,之後將通道的資料排出到程式B所在的緩衝區,程式B的程式程式碼就可以對程式B所在的緩衝區的資料進行一系列的操作了。這個過程並沒有出現Selector(選擇器),那麼選擇器是幹嘛的呢?說得簡單點,選擇器的作用是一個觀察者,可以讓執行緒監聽各個註冊通道中的事件,使得執行緒可以對註冊事件進行操作(比如連線的建立、斷開等)。

Channel可以理解為通道,是執行I/O操作的入口,資料可以流向通道,也可以從通道流出。

Channel介面的實現在Java中主要有以下幾個:

  • FileChannel
  • DatagramChannel
  • SocketChannel
  • ServerSocketChannel

Buffer則是緩衝區,緩衝區是裝了固定數量的容器,緩衝區的作用像一個儲存器,緩衝區可以被寫滿或者被釋放。如果把通道比作是I/O的入口,那麼緩衝區則是I/O的來源,通道的資料需要從緩衝區得到,通道的資料排出的地方也是緩衝區。如果理解TCP/IP的傳輸協議,這點應該不難理解。

Buffer介面的主要實現有:

  • ByteBuffer(位元組緩衝區)
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

Selector是選擇器,選擇器通常與通道關聯,一個執行緒可以使用選擇器處理多個通道(可以理解為Web伺服器的多個連線),使用選擇器可以方便執行緒處理多個連線的觸發事件,比如開啟了連線、傳送了資料以及斷開連線等事件。而需要使用Selector僅僅需要將通道(連線)註冊到Selector上就可以。

所以Selector與Channel的關係是這樣的:

Selector與Channel的關係

從圖中可以看到,服務端的執行緒通過使用Selector可以註冊多個連線Connection物件,這樣每個Connection主要監聽的事件發生,那麼就可以及時通知服務端的Thread物件,從而進行下一步的處理。區別於傳統的IO模型——每次有新的連線都需要阻塞等待,直到處理結束後再處理下一個Connection。可以看到,這種處理模型在高併發的場景會馬上崩掉。

相關文章