NIO浅析(1)

NIO浅析

1、为什么使用NIO?

一句话:都是阻塞惹的祸

BIO服务端存在请求阻塞阻塞,不能同时处理多个客户端的连接请求。

有人提出在服务端accept后,创建线程去处理请求。这种方式有不足:互联网高并发场景下,过多的线程会导致OS的频繁切换,大大影响性能,即使使用线程池创建线程。

在这里插入图片描述
以上用线程池会产生请求时间长,拒绝服务,但是服务器资源可能并未高效率使用。

2、使用NIO的三个点

A、Selector

为什么使用selector
因为比较老的办法是,server的一个线程需要不断while(true)去轮询来 发现是否有新连接或者是否有数据读写操作。在高并发情况下,性能是很低的
选择器,一个选择器可以检测多个通道channel
在这里插入图片描述
具体使用:

在这里插入图片描述

selectKeys: selector监听到就绪的channel的keys。

先获取到所有keys,再对key进行循环判断。对key(是否连接判断、是否可读判断、是否写判断、数据是否已经发送)进行判断, 对不同情况进行处理。

B、channel

数据来源及去向,类比socket

在这里插入图片描述

首先创建ServerSocketChannel , 绑定端口号,随后注册到Selector,让Selector检测连接进来,指定使用非阻塞方式。

在这里插入图片描述
一旦进入key.isAccept()后,创建socketChannel通道,并注册到selector上监听数据是否到达。

在这里插入图片描述
一旦进入isReadable()后,交给一个线程池的一个任务去异步处理。

在这里插入图片描述
一定要进行cancel()操作,原因:因为是交给线程池异步处理,所以存在异步未处理,key又被selector监听一次,再次交给线程处理,会产生重复select,从而再次产生数据。虽然我们对key进行以下处理:

在这里插入图片描述
Selector会产生2个集合(所有注册通道集合,就绪的key集合),上述代码只是移除就绪的key集合。
但是register集合中未被移除,还是存在被Select的可能,所以一定到取消注册(key.cancel())。

C、Buffer

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
sc.read(),写到buffer中。

1、形象比喻BIO&&NIO

在这里插入图片描述
2、多路复用解释
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值