BIO
- server 端有个 serverSocket 监听端口
一个 客户端 socket 对监听端口发起连接,那么 serverSocket 创建一个工作线程和socket 来与客户端的 socket 进行同步阻塞式的数据通信
缺点
一个客户端 socket 连接,serverSocket 就要创建一个工作线程和socket 进行数据通信,如果客户端 socket 过多,服务端会创建大量线程,服务器会卡死
- 即使使用线程池来负责
- 限制了服务端的客户端通信数量
- 即使这段通信长期没有交互,浪费资源
NIO
- 服务端有一个 selector 线程
- 一个客户端 socket 进行连接,会创建一个 channel 注册到 selector 上
- selector 会轮询这些注册的 channel,当channel 有读写事件,即客户端进行了数据传输,selector 会获取对应的 channel
- selector 会创建一个工作线程(可以用线程池),通过 buffer 与 channel 进行同步非堵塞的数据交互,然后通过 channel 将响应返回客户端
- 然后工作线程销毁(或者放回线程池)
优缺点
- NIO 通过内存中的channel 和 selector 线程和若干个少量的工作线程就可以与大量的客户端进行连接
- 同步,就是工作线程还是需要对 channel 的数据进行读取、写入,这个过程是同步的
- 非堵塞,就是不论多少客户端的连接和请求都能进来,只要注册对应的 channel ,selector 轮询到有事件的 channel,就会开一个工作线程进行处理
AIO
- AIO是基于Proactor模型的,就是异步非阻塞模型。
步骤
- 每个连接发送过来的请求,都会绑定一个buffer,然后通知操作系统去异步完成读,此时你的程序是会去干别的事儿的,等操作系统完成数据读取之后,就会回调你的接口,给你操作系统异步读完的数据。
- 然后你对这个数据处理一下,接着将结果往回写。
- 写的时候也是给操作系统一个buffer,让操作系统自己获取数据去完成写操作,写完以后再回调通知你。
同步阻塞、同步非阻塞、异步非阻塞
- BIO:同步阻塞。这个其实不是针对网络编程模型来说的,是针对文件IO操作来说的。因为用BIO的流(FileInputStream)读写文件,工作线程发起个IO请求直接卡住,必须等着搞完了这次IO才能返回
- NIO: 同步非阻塞?就是说工作线程通过 NIO 的 FileChannel 发起个文件IO操作,发起之后就返回了,工作线程可以干别的事,这就是非阻塞。但是接下来工作线程还得不断的去轮询操作系统,看IO操作完事了没有。
AIO为啥是异步非阻塞?就是说通过AIO发起个文件IO操作之后,你立马就返回可以干别的事儿了,接下来你也不用管了,操作系统自己干完了IO之后,告诉你说ok了。同步就是自己还得主动去轮询操作系统,异步就是操作系统反过来通知你。
你也可以基于AIO的文件读写的api去读写磁盘文件,你发起一个文件读写的操作之后,交给操作系统,你就不去管他了,直到操作系统自己完成之后,会来回调你的一个接口,通知你说,ok,这个数据读好了,那个数据写完了