上一篇 <<<BIO模型的缺陷
下一篇 >>>select、poll、epoll的區(qū)別
產(chǎn)生緣由
因?yàn)锽IO存在線(xiàn)程阻塞,偽異步的話(huà)也會(huì)存在線(xiàn)程安全和資源浪費(fèi)情況,而NIO恰好能解決這些問(wèn)題。
底層原理關(guān)鍵詞
面向與緩沖區(qū)
基于通道實(shí)現(xiàn)非阻塞式io
多路io復(fù)用實(shí)現(xiàn)(選擇器)

通道(Channel)----TCP鏈接道路
通常我們nio所有的操作都是通過(guò)通道開(kāi)始的,所有的通道都會(huì)注冊(cè)到統(tǒng)一個(gè)選擇器(Selector)上實(shí)現(xiàn)管理,在通過(guò)選擇器將數(shù)據(jù)統(tǒng)一寫(xiě)入到 buffer中。
緩沖區(qū)(Buffer)------加快數(shù)據(jù)的讀取
Buffer本質(zhì)上就是一塊內(nèi)存區(qū),可以用來(lái)讀取數(shù)據(jù),也就先將數(shù)據(jù)寫(xiě)入到緩沖區(qū)中、在統(tǒng)一的寫(xiě)入到硬盤(pán)上。
選擇器(Selector)------通道的管理,實(shí)現(xiàn)多路IO復(fù)用機(jī)制---一個(gè)線(xiàn)程處理多個(gè)TCP請(qǐng)求。
Selector可以稱(chēng)做為選擇器,也可以把它叫做多路復(fù)用器,可以在單線(xiàn)程的情況下可以去維護(hù)多個(gè)Channel,也可以去維護(hù)多個(gè)連接;
線(xiàn)程--完成具體的業(yè)務(wù)

Nio技術(shù)多路IO復(fù)用底層實(shí)現(xiàn)原理
多路:實(shí)際指的就是多個(gè)不同的tcp連接
復(fù)用:一個(gè)線(xiàn)程可以維護(hù)多個(gè)不同的io操作
好處: 占用cpu資源非常小、保證線(xiàn)程安全問(wèn)題
手寫(xiě)偽NIO代碼
public class SocketNioTcpServer {
private static List<SocketChannel> listSocketChannel = new ArrayList<>();
private static ByteBuffer byteBuffer = ByteBuffer.allocate(512);
public static void main(String[] args) {
try {
// 1.創(chuàng)建一個(gè)ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 2. 綁定地址
ServerSocketChannel bind = serverSocketChannel.bind(new InetSocketAddress(9090));
serverSocketChannel.configureBlocking(false);
while (true) {
/**channel管道:TCP數(shù)據(jù)傳輸?shù)耐ǖ?/
SocketChannel socketChannel = serverSocketChannel.accept();
if (socketChannel != null) {
/**通道加入到選擇器中*/
socketChannel.configureBlocking(false);
listSocketChannel.add(socketChannel);
}
/**輪詢(xún)選擇器下的所有通道信息,利用buffer緩存機(jī)制讀取數(shù)據(jù)*/
for (SocketChannel scl : listSocketChannel) {
try {
int read = scl.read(byteBuffer);
if (read > 0) {
byteBuffer.flip();
Charset charset = Charset.forName("UTF-8");
String receiveText = charset.newDecoder().decode
(byteBuffer.asReadOnlyBuffer()).toString();
System.out.println(Thread.currentThread().getName()+" receiveText:" + receiveText);
}
listSocketChannel.remove(scl);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
推薦閱讀:
<<<OSI七層模型與層上協(xié)議
<<<TCP的三次握手建立鏈接和四次揮手釋放鏈接
<<<TCP、UDP及Socket代碼示例
<<<Https的1.0、2.0協(xié)議及長(zhǎng)短鏈接區(qū)別
<<<Linux系統(tǒng)的五種IO模型
<<<BIO和NIO區(qū)別
<<<BIO模型的缺陷
<<<select、poll、epoll的區(qū)別
<<<Redis為什么單線(xiàn)程能夠支持高并發(fā)
<<<Netty初識(shí)
<<<Netty的粘包和拆包問(wèn)題分析
<<<粘包和拆包問(wèn)題解決方案匯總
<<<序列化與反序列化知識(shí)點(diǎn)匯總
<<<MessagePack反序列化使用示例
<<<Marshalling在Netty中的使用