什么是NIO
NIO(Non Block IO)一般對應的是BIO,非阻塞IO相對阻塞IO的區別在于獲取IO狀態的過程是非阻塞的,好處是可以用更少的線程管理更多的鏈接。比如目前有10000個鏈接,而同時活躍的只有200個,如果用BIO的話必須得10000個線程才能管理,而NIO只需200個線程即可。而在java中,線程是相對寶貴的資源,每個線程棧大小默認為1MB,而且多線程之間的切換也會影響性能,因此NIO會明顯提高后臺能夠處理的鏈接數。
原生NIO編程
原生的NIO編程主要有幾個概念:
- Channel:通道,泛指可以進行數據傳輸的通道,比如一個Socket,Channel默認是雙向的。
- Buffer:和channel進行數據交換的數據緩沖區,可以把數據從buffer寫進channel或從channel讀入buffer
- Selector: NIO實現的關鍵,可以用一個selector管理多個channel,對于網絡來說,相當于可以用一個線程來管理多個鏈接。channel可以向selector注冊并指定感興趣的事件,當事件發生時可以進行相應的處理
NIO編程中一般有兩種channel。ServerSocketChannel代表服務端的channel,它可以綁定端口,監聽鏈接連接的請求。SocketChannel代表客戶端向服務端發起的鏈接,可以認為是一個實際的TCP鏈接,它可以監聽數據的讀取,寫入等事件。下面是一個服務端編程的例子。
Netty
Netty出現的目的是為了提高nio編程的效率和性能,提供了更好的方法和工具來方便網絡編程的開發。具體的netty介紹就不復述了,可以去看netty官網。后面的學習主要基于netty的4.1.33.Final版本進行。
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.33.Final</version>
</dependency>