以下僅僅介紹各個組件的用途與爲什麼會出現這些組件,不提供API的詳解
NIO是什麼?
全稱new input output。針對於文件系統的IO,提供內存映射以提高IO效率;對於網絡IO,提供一個線程可以管理多個連接的能力。
爲什麼能提高IO效率?
本地文件系統
針對於本地文件系統,不支持選擇通道+IO多路複用。文件要被應用所訪問到,路徑爲 磁盤-->>>內核空間-->>>用戶空間,磁盤到內核空間有一個DMA控制器,DMA控制器從磁盤加載數據是不需要消耗CPU的,但內核空間到用戶空間需要消耗CPU,NIO中的buffer組件能提供內存映射,避免了內核空間把文件內容進行中轉的CPU消耗,如下圖,圖1爲沒用內存映射,圖2用了內存映射
網絡IO
針對於網絡IO,支持可選擇通道+多路複用,提供了以下模型,選擇器可以選擇就緒的通道進行操作,如下圖:
socket+nio與傳統socket+bio優勢
一個選擇器可以管理多個客戶端通道;如果是傳統的方式,由於socket是阻塞的,所以爲了解決多個客戶端連接的問題,需要開多個線程,一個線程處理一個客戶端,由於線程資源寶貴且數量有上限,無法處理併發高的情況。
組件
Buffer緩衝區
buffer是用於承載於通道兩端實體數據的容器,類圖如下:
只有ByteBuffer才能被管道所使用,因爲操作系統的數據存儲都是基於字節的。字節緩衝區又分爲直接緩衝區與非直接緩衝區,直接緩衝區就是用了內存映射。
直接緩衝區的好處:
1. 基於內存映射,IO效率高
2. 由操作系統分配內存,所以不佔用JVM的內存
直接緩衝區的壞處:
1. 需要操作系統來分配調度,所以代價昂貴
視圖緩衝區與字節緩衝區
視圖緩衝區只能由字節緩衝區生成,視圖緩衝區是原始類型的緩衝區,與原緩衝區數據共享,但是單獨維護了limit,position等重要屬性。
通道Channel
通道是連接於兩端實體的管道,兩端數據的傳遞把數據放入buffer,然後經過管道傳輸。
注意: 只有繼承了SelectableChannel的之類才能配合選擇器使用
通道類圖如下:
FileChannel不支持選擇通道+多路複用,因爲沒有繼承SelectableChannel
SelectionKey
由通道註冊到選擇器後返回的對象,封裝了 選擇器與通道的關係和通道的就緒狀態和感興趣的操作。
Selector選擇器
用於選擇出已經準備就緒的通道。
關於針對於網絡IO各個組件的關係圖如下: