主类:
服务端监听线程:
服务端处理线程:
客户端:
3.2 NIO
同步非阻塞IO之NIO:服务器端保存一个Socket连接列表,然后对这个列表进行轮询,如果发现某个Socket端口上有数据可读时说明读就绪,则调用该socket连接的相应读操作。如果发现某个 Socket端口上有数据可写时说明写就绪,则调用该socket连接的相应写操作。如果某个端口的Socket连接已经中断,则调用相应的析构方法关闭该端口。这样能充分利用服务器资源,效率得到了很大提高,在进行IO操作请求时候再用个线程去处理,是一个请求一个线程
。Java中使用Selector、Channel、Buffer来实现上述效果。
每个线程中包含一个
Selector
对象,它相当于一个通道管理器,可以实现在一个线程中处理多个通道的目的,减少线程的创建数量。远程连接对应一个channel,数据的读写通过buffer均在同一个 channel
中完成,并且数据的读写是非阻塞的。通道创建后需要注册在 selector
中,同时需要为该通道注册感兴趣事件(客户端连接服务端事件、服务端接收客户端连接事件、读事件、写事件), selector
线程需要采用 轮训
的方式调用 selector
的 select
函数,直到所有注册通道中有兴趣的事件发生,则返回,否则一直阻塞。而后循环处理所有就绪的感兴趣事件。以上步骤解决BIO的两个瓶颈: 正如你所看到的,这些通道涵盖了UDP和TCP网络IO,以及文件IO。以下是Java NIO里关键的buffer实现:
在微服务阶段,一个请求可能涉及到多个不同服务之间的跨服务器调用,如果你想实现高性能的PRC框架来进行数据传输,那就可以基于Java NIO做个支持长连接、自定义协议、高并发的框架,比如Netty。Netty本身就是一个基于NIO的网络框架, 封装了Java NIO那些复杂的底层细节,给你提供简单好用的抽象概念来编程。比如Dubbo底层就是用的Netty。
3.3 AIO
AIO是异步非阻塞IO,相比NIO更进一步,进程读取数据时只负责发送跟接收指令,数据的准备工作完全由操作系统来处理。
4 参考
IO说:https://blog.csdn.net/u013177446/article/details/65936341
爆赞TCP讲解:https://b23.tv/tMxwQV
通俗说IO:https://www.cnblogs.com/LBSer/p/4622749.html
小仙IO:https://t.1yb.co/iEAW
本文分享自微信公众号 - sowhat1412(sowhat9094)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。