java中的几种IO模型
我会陆续的讲解一下BIO/NIO/AIO的一些概念性的不同,并将其中的一些不同点做一下总结。这篇文章主要对BIO进行一些概念性的梳理。
一、传统的BIO
网络编程的基本模型是Clientt/Server模型,其中服务端负责提供位置信息(绑定ip和端口号)客户端负责通过连接操作向服务端监听的地址发送连接请求,通过三次握手建立连接。
1、BIO通信模型
传统的同步阻塞式通信模型BIO的服务端通常由一个独立的Acceptor线程负责箭筒客户端的链接,它在接收到客户端的链接请求之后为每一个客户端创建一个新的线程进行链路处理,处理完之后通过输出流返回给客户端,线程销毁。也就是说客户端的请求数与服务端的链路处理线程是一对一的关系。
2、BIO的不足
该模型最大的问题就是缺乏弹性伸缩能力,当客户端的并发访问量增加后,服务端的线程个数和客户端的并发访问量呈1:1的关系,由于服务器的资源有限,当线程数增加后,系统的性能将急剧下降,随着线程数的继续增大,势必会导致系统发生线程的堆栈溢出,创建线程失败等问题。从而导致服务端进程宕机,不能提供服务。
为了改进这一线程一连接的模型可以通过线程池或消息队列实现一个或者多个线程处理N个客户端的伪异步请求模型。
二、伪异步IO
伪异步IO模型是服务端在启动时创建一个服务器处理类的线程池,当接收到新的客户端连接时,将请求socket封装成一个Task,然后调用线程池的execute方法执行。从而避免每个请求都创建一个新的线程。
伪异步IO的弊端
由于对java输入流IInputStream进行读取操作时,它会一直阻塞下去,知道发生以下三种事件:
有数据可读;
可用数据已经读取完毕;
发生空指针异常或者IO异常
这意味着当对方发送请求或者应答消息比较缓慢,或者网络传输较慢时,读取输入流一方的通信线程将被长时间阻塞,从而导致级联故障。