|
产生缘由 因为BIO存在线程阻塞,伪异步的话也会存在线程安全和资源浪费情况,而NIO恰好能解决这些问题。
底层原理关键词 1)面向与缓冲区
2)基于通道实现非阻塞式io
3)多路io复用实现(选择器)
通道(Channel)----TCP链接道路
通常我们nio所有的操作都是通过通道开始的,所有的通道都会注册到统一个选择器(Selector)上实现管理,在通过选择器将数据统一写入到 buffer中。
缓冲区(Buffer)------加快数据的读取
Buffer本质上就是一块内存区,可以用来读取数据,也就先将数据写入到缓冲区中、在统一的写入到硬盘上。
选择器(Selector)------通道的管理,实现多路IO复用机制---一个线程处理多个TCP请求。
Selector可以称做为选择器,也可以把它叫做多路复用器,可以在单线程的情况下可以去维护多个Channel,也可以去维护多个连接;
线程--完成具体的业务
Nio技术多路IO复用底层实现原理 多路:实际指的就是多个不同的tcp连接
复用:一个线程可以维护多个不同的io操作
好处: 占用cpu资源非常小、保证线程安全问题
手写伪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.创建一个ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 2. 绑定地址
ServerSocketChannel bind = serverSocketChannel.bind(new InetSocketAddress(9090));
serverSocketChannel.configureBlocking(false);
while (true) {
/**channel管道:TCP数据传输的通道*/
SocketChannel socketChannel = serverSocketChannel.accept();
if (socketChannel != null) {
/**通道加入到选择器中*/
socketChannel.configureBlocking(false);
listSocketChannel.add(socketChannel);
}
/**轮询选择器下的所有通道信息,利用buffer缓存机制读取数据*/
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();
}
}
} |
----------------------------
原文链接:https://www.jianshu.com/p/13ef4c5976e8
程序猿的技术大观园:www.javathinker.net
[这个贴子最后由 flybird 在 2021-06-24 10:44:07 重新编辑]
|
|