IO编程
java BIO
网络编程的基本模型是基于服务器/客户端,二者通过三次握手来连接,并通过socket通信。采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,在接收到客户端请求后创建一个单独的线程与服务器交互,通过输出流将结果返回给客户端,线程销毁。
缺点:缺乏弹性伸缩能力。在高并发的情况下客户端进程与服务端进程保持1:1,占用大量系统资源。
伪异步IO
为了改进这种一连接一线程的模型,我们可以使用线程池来管理这些线程,实现1个或多个线程处理N个客户端的模型(但是底层还是使用的同步阻塞I/O),通常被称为“伪异步I/O模型“。
我们知道,如果使用CachedThreadPool线程池,其实除了能自动帮我们管理线程(复用),看起来也就像是1:1的客户端:线程数模型,而使用FixedThreadPool我们就有效的控制了线程的最大数量,保证了系统有限的资源的控制,实现了N:M的伪异步I/O模型。
但是,正因为限制了线程数量,如果发生大量并发请求,超过最大数量的线程就只能等待,直到线程池中的有空闲的线程可以被复用。而对Socket的输入流就行读取时,会一直阻塞,直到发生:
- 有数据可读
- 可用数据以及读取完毕
- 发生空指针或I/O异常
所以在读取数据较慢时(比如数据量大、网络传输慢等),大量并发的情况下,其他接入的消息,只能一直等待,这就是最大的弊端。
NIO和AIO
NIO
一般称非阻塞IO,提供了两种新的套接字通道SocketChannel和ServerSocketChannel。对于低负载使用同步阻塞可以提升开发效率和可维护性,对于高并发应使用NIO
- 缓冲区 buffer 实际上是一个数组,数据的读入和写入都通过它
- 通道 channel 区别于流 全双工 同时读写
- 多路复用器 selector可以不断轮询注册在其上的channel,如果该channel上发生读写,则可以通过selectorKey获得通道上的数据,进行I/O操作
%NODE_PATH%\bin;