一、基本概念
对于 IO(InputStream、OutputStream) 我们应该比较熟悉,IO 不仅仅针对文件的操作,网络编程 Socket 的通信,也是IO操作。输入、输出流(InputStream、OutputStream)用于读取或写入字节,如操作图片、视频等。
同时在了解 IO 的前提下,我们还需要知道几个概念:阻塞
与非阻塞
,同步
与异步
。
阻塞
与非阻塞
是指:线程访问资源,该资源是否准备就绪的一种处理方式。
例如线程 A 去访问一个资源,该资源正在处理中,于是线程 A 什么都不干,就在这里一直等着,直到资源处理完毕,这就是阻塞
。
再来看一个聪明点的线程 B,它去访问一个资源,该资源也在处理中,于是线程 B 就再去请求下一个资源,如果下一个资源也在处理中,那么它还可能去请求第三个、第四个资源。
同步
与异步
是指访问数据的一种机制。
例如线程 A 去请求资源,线程 A 要定时的读取,判断数据有没有准备好,如果准备好了,就返回数据,这就是同步
。
例如线程 B 去请求资源,B 不会主动去看看资源有没有准备好,而是资源准备好之后,会来通知线程 B,这就是异步
。
以上模式两两组合,就可以分为同步阻塞(BIO)
、同步非阻塞(NIO)
、异步阻塞
、异步非阻塞(AIO)
四种。
二、BIO
BIO(Block IO)同步阻塞 IO,IO 在进行读写的时候,这个线程是阻塞的,不能去做其他的事情,这是一种非常传统、简单的通信模式,并发处理能力非常低,并且线程之间访问资源通信的时候耗时也是比较久,相应的也依赖网速与带宽。
例如有一台服务器,可以接受多个客户端请求,那么使用 BIO 是可以实现的。但是为了一个用户的请求而单独启动一个线程,开销应该不小吧。Java 语言对线程的实现是比较重量的,启动或销毁线程,都会有明显开销,每个线程都有单独的线程棧占用明显的内存。引入线程池,就能很大程度的避免不必要的开销。
这种情况适合连接数并不多,只有最多几百个连接的普通应用,能比较好的进行工作,但如果连接数量剧增,肯定是不可取的。
三、NIO
NIO(New IO 或 Non-Block IO) 同步非阻塞 IO,NIO 采用的是一种多路复用的机制,利用单线程主动轮询事件。
当客户端与服务端进行连接的时候,实际上是与 Selector 进行注册,注册完毕之后会有双向通道 Channel,每个客户端注册后都会有一个 Channel。
NIO 的非阻塞
是指,Selector 会轮询多个 Channel,定位就绪的 Channel 来决定做什么,如果没有数据,Selector 会跳过该 Channel,而不会阻塞的等待数据,能有效避免大量连接数时,频繁线程的切换带来的性能或各种问题。
NIO 的同步
是指,这个线程仍然要定时的读取 Stream,判断数据有没有准备好。
这里的的 Selector 是一个单线程,可以处理成百上千个 Channel,但如果是高并发、大负载,NIO 还是处理不了,这时就需要新的线程模型。NIO 有三种线程模型:
1、Reactor 单线程模型:
单个线程完成所有事情包括接收客户端的TCP连接请求,读取和写入套接字数据等,上面所讲的就是单线程模型。
2、Reactor 多线程模型:
Rector多线程模型与单线程模型最大的区别就是:有专门一个 NIO 线程——Acceptor 线程用于监听服务端,接收客户端的TCP连接请求;另外还有一组 NIO 线程处理真实的IO操作。
网络IO操作-读、写等由一个NIO线程池负责,线程池可以采用标准的JDK线程池实现,它包含一个任务队列和N个可用的线程,由这些NIO线程负责消息的读取、解码、编码和发送;
从上图中可看出,相比于单线程模型,从单线程中由一个线程即监听连接事件、读写事件、由完成数据读写,拆分为由一个线程专门监听各种事件,再由专门的线程池负责处理真正的IO数据读写。
3、主从 Reactor 多线程模型
主从Reactor线程模型与Reactor多线程模型的最大区别就是有一组NIO线程处理连接、读写事件。
相比于多线程模型,主从模型吧一个线程监听连接事件,改为线程池的多个线程监听已经建立连接的套接字的数据读写事件,另外一个与多线程模型一样有专门的线程池处理真正的IO操作。
四、AIO
AIO 是在 NIO 的基础上引入异步通道的概念,实现异步非阻塞式的IO处理。
AIO 不需要通过多路复用器对注册的通道进行轮询操作即可实现异步读写。
NIO 采用轮询的方式,一直在询问数据是否准备就绪,如果准备就绪发起处理。但是 AIO 就不需要了,应用程序向操作系统注册 IO 监听,然后继续做自己的事情。操作系统发生 IO 事件,并且准备好数据后,在主动通知应用程序,触发相应的函数。由于应用程序不是“轮询”方式而是订阅-通知方式,所以不再需要selector轮询,由channel通道直接到操作系统注册监听。