為什麼有NIO
BIO 即阻塞的I/O,不管是磁盤還是網絡,數據通過OutputStream寫入或者InputStream讀取的時候都有可能阻塞,一旦阻塞,線程會失去CPU的使用權,大規模併發的時候是不能被接收的。解決的方式是使用線程池管理,但是如像微信這種,服務器可能需要保持幾百萬的HTTP連接,但是不是每時每刻都是在傳遞數據,這種情況下,不可能創建這麼多線程來保持連接,這個時候就需要考慮NIO了。
NIO的類圖如下:
channel和Buffer:通道,類似汽車,數據總是從channel讀取進入Buffer,或者寫入的時候,先寫入到Buffer,在寫到channel,如下圖所示channel和Buffer的關係:
Selector: 是一個對象,類似汽車的調度指揮中心,可以監聽多個channel事件,如連接打開,單線程可以監聽多個channle的狀態。
java NIO Channel的常見實現類:
- FileChannel
- DatagramChannel
- SocketChannel
- ServerSocketChannel
java NIO Buffer的創建實現類:
- ByteBuffer
- CharBuffer
- DoubleBuffer
- FloatBuffer
- IntBuffer
- LongBuffer
- ShortBuffer
還有一個MappedByteBuffer,內存映射文件
Selectors
Selector 允許單線程管理多個Channel,比如你的程序打開了多個Channel,每個Channel的流量不大。下面為Select監聽多個Channel的圖
Channel的register方法可以將Selector註冊進去,然後調用selector.select()方法,這個方法將阻塞,直到有一個已經註冊channel的事件準備就緒。一旦select()方法返回,就能出來這些事件。事件比如connection,data被接收等。
閱讀更多 全棧獨立開發者 的文章