1、同步阻塞式IO(BIO)
就是服务端创建一个ServerSocket,然后客户端用一个Socket去连接那个ServerSocket,然后ServerSocket接收到一个Socket的连接请求就创建一个Socket和一个线程去跟那个Socket进行通信。
然后客户端和服务端的socket,就进行同步阻塞式的通信,客户端socket发送一个请求,服务端socket进行处理后返回响应,响应必须是等处理完后才会返回,在这之前啥事儿也干不了,这可不就是同步么。
这种方式最大的坑在于,每次一个客户端接入,都是要在服务端创建一个线程来服务这个客户端的,这会导致大量的客户端来的时候,服务端的线程数量可能达到几千甚至几万,几十万,这会导致服务器端程序的负载过高,最后崩溃死掉。
要么你就是搞一个线程池,固定线程数量来处理请求,但是高并发请求的时候,还是可能会导致各种排队和延时,因为没那么多线程来处理。
不是针对网络编程模型来说的,是针对文件IO操作来说的,因为用BIO的流读写文件,是说你发起个IO请求直接hang死,必须等着搞完了这次IO才能返回。
磁盘文件的IO读写,FileInputStream,BIO,卡在直到你读写完成了才可以。
2、同步非阻塞IO(NIO)
NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的、基于通道的IO操作,非阻塞的。
Selector 一般称为选择器 ,也可以翻译为多路复用器。
Connect(连接就绪)
Accept(接受就绪)
Read(读就绪)
Write(写就绪)
多路复用可以理解为,只负责接待并放入执行队列,然后由执行器处理并直接返回。
多路复用器 Selector,是 NIO 的基础,多路复用器提供选择已经就绪的任务的能力,简单来说,Selector 会不断轮询注册 Channel,如果某个 Channel 上面有新的TCP连接接入、读、写事件,这个 Channel 就处于就绪状态,会被 Selector 轮询出来,然后通过 SelectionKey 可以获取就绪的 Channel 进行 I/O 操作。一个多路复用器可以同时轮询多个 Channel,通过这个机制可以接入成千上万的客户端。
这里的核心就是一个客户端不是时时刻刻都要发送请求的,没必要死耗着一个线程不放吧,所以NIO的优化思想就是一个请求一个线程。只有某个客户端发送了一个请求的时候,才会启动一个线程来处理。处理完后关了工作线程。
所以为啥是非阻塞呢?
因为无论多少客户端都可以接入服务端,客户端接入并不会耗费一个线程,只会创建一个连接然后注册到selector上去罢了,一个selector线程不断的轮询所有的socket连接,发现有事件了就通知,然后就启动一个线程处理一个请求即可。但是在处理的过程中,还是要先读取数据后再返回的,这是个同步的过程。
比如说:通过NIO的FileChannel发起个文件IO操作,其实发起之后就返回了,你可以干别的事儿,这就是非阻塞,但是接下来你还得不断的去轮询操作系统,看IO操作完事儿了没有。
3、异步IO(AIO)
即经典的reactor设计模式,也称为异步非阻塞IO。
每个连接发送过来的请求,都会绑定一个buffer,然后通知操作系统去异步完成读,此时你的程序是会去干别的事儿的,等操作系统完成数据读取之后,就会回调你的接口,给你操作系统异步读完的数据。
现NIO是常用的,并且上面提到,NIO支持面向缓冲区的、基于通道的IO操作,那是如何操作缓冲区的呢?
下节我们进行讲解,谢谢,如喜欢,请关注我,免费学习更多技术知识。