java的IO机制主要分为BIO,NIO,AIO
一 BIO
- Block-IO:InputStream和OutputStream,Reader和Writer
1.1 BIO建立的连接
服务端创建一个ServerSocket,然后客户端用一个Socket 连接这个ServerSocket,然后ServerSocket接收到一个Socket客户端的连接请求就会在自己内部创建一个Socket和一个线程去跟客户端的Socket进行通信。
然后客户端和服务端的socket,就进行同步阻塞式的通信,客户端socket发送一个请求,服务端socket进行处理后返回响应,他这个响应必须是等处理完后才会返回,在这之前什么都干不了。(这可不就是同步么)
1.2 BIO请求回复过程
BIO基于流模型实现的,交互方式是同步阻塞,读写线程完成之前会一直阻塞
应用程序发起请求的时候,程序线程陷入阻塞状态等待返回的数据
1.3 BIO的坑
这种方式最大的坑在于,每次一个客户端接入,都是要在服务端创建一个线程来服务这个客户端的,这会导致大量的客户端的时候,服务端的线程数量可能达到几千甚至几万,几十万,这会导致服务器端程序的负载过高,有比较高风险。
当然我们也可以搞一个线程池,固定线程数量来处理请求,但是高并发请求的时候,还是可能会导致各种排队和延时,因为没那么多线程来处理。
二 NIO
- NonBlock-IO:构建多路复用的、同步非阻塞的IO操作 ByteBuffer CharBuffer DoubleBuffer FloatBuffer IntBuffer LongBuffer ShortBuffer MappedByteBuffer
2.1 NIO建立的连接模型
每个客户端连接到服务端,服务端selector只会创建一个channel维持两者的联系,seletor会轮询每个channel,如果有请求在channel里就取出来创建一个线程进行处理返回回去(此处的线程也可以通过线程池管理服务可以创建的线程数),同时客户端也会在发送数据后轮询这个channel,看自己需要的数据准备好没有
2.2 NIO请求回复过程
2.3 为什么说NIO是同步非阻塞的
非阻塞说的是无论多少客户端都可以接入服务端,客户端接入并不会耗费一个线程,只会创建一个连接然后注册到selector上去罢了,一个selector线程不断的轮询所有的socket连接,发现有事件了就启动一个线程处理一个请求,客户端这边不需要阻塞在这,只需要反复的查看数据有没有准备好就行。
同步指的是在这个处理的过程中,我们还是要先读取数据,处理,再返回的,这个地方是个同步的过程。
2.4 NIO核心
NIO中select,poll,epoll的区别.png
三 AIO
AIO demo
各IO机制的对比与选型
BIO适合连接数小且固定的架构,对服务器资源要求比较高 NIO适用于连接数目多且较短的架构比如聊天服务器 AIO适用于连接数多且较长的架构中比如相册服务器