NIO簡介
- NIO 是面向緩沖區(或者說面向塊)編程的, 因為Buffer底層本質上就是內存塊。數據被讀取到一個緩沖區, 稍后再被它處理, 需要時數據可在緩沖區前后移動, 從而增加了處理過程中的靈活性, 使用它可以提供非阻塞式的高伸縮性網絡。
- NIO的非阻塞模式, 當使用一個線程從某通道發送請求或讀取數據, 但它僅能得到目前可用的數據, 如果目前沒有數據可用時, 就什么都不會獲取, 而不是保持線程阻塞, 所以直至數據變的key讀取之前, 該線程可用繼續做其他事情。
- 非阻塞模式同理, 一個線程請求寫入一些數據到某通道, 但不需要等待它完全寫入, 該線程就可以去干別的事情了。
- 核心理解: 用一個線程來處理多個操作, 不用像BIO那樣必須一個線程處理一個操作, 減少了cpu資源調度的損耗。
- 此外需要注意的是: HTTP2.0 使用了多路復用的技術, 做到了使用同一個連接並發處理多個請求, 而且並發請求的數量比HTTP1.1大了好幾個數量級。
三大組件
-
Buffer(緩沖區)
- 值得注意的是沒有BooleanBuffer哈
-
Channel(管道)
- 本身是一個接口
- 繼承該接口的接口有:
- ReadableByteChannel(可讀的字節數組管道)
- InterruptibleChannel(可中斷的管道)
- NetworkChannel(網絡管道)
- WritableByteChannel(可寫的字節數組管道)
- SelChImpl(Select Change Implements?接口注釋寫的是一個允許轉換(甚至更多)的接口, 暫時不去細看了)
- AsynchronousChannel(異步管道)
- 實現了該接口的類有:
- 繼承該接口的接口有:
- 本身是一個接口
-
Selector(選擇器)
- 本質是一個抽象類
- Selector <- AbstractSelector(抽象選擇器) <- SelectorImpl(這其實還是個抽象類) <- WindowsSelectorImpl(窗口選擇器實現類)
- 本質是一個抽象類
三者的關系
- 每個channel 都會對應一個Buffer
- Selector 對應一個線程, 該線程對應多個channel(管道)
- 上圖表示有三個channel注冊到了此selector程序
- 程序切換到哪個channel是由事件(Event)決定的
- Selector 會根據不同的事件, 在各個通道上切換
- Buffer本質上就是一個內存塊, 底層有一個數組, 數據存放於其中
- 數據的讀取寫入是通過Buffer的, 此點與BIO有本質區別(BIO中要么是輸入流, 要么是輸出流, 不能雙向傳輸)
- NIO 的Buffer可以讀也可以寫, 但是需要flip()方法切換
- channel 是雙向的, 可以返回底層操作系統的情況, 如Linux底層的操作系統通道就是雙向的