BIO模型(Bkicj-lo 同步阻塞IO)
一个线程处理一个请求,其他线程阻塞在哪
io流操作中accept()和read()方法会阻塞在哪
同步并阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求的服务器端就需要启动一个线程进行处理,
如果这个连接不做任何事情造成不必要的线程开销。
需要开启多个线程,线程的切换和等待都带来非常大的开销
适用场景:解决客户端数量比较小,并且固定的架构,这种方式对服务器资源要求比较高。JDK1.4之前的唯一选择,程序简单,容易理解。
NIO模型(同步非阻塞)
同步非阻塞(JDK1.4开始),服务器实现模式为一个线程处理多个请求,既客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有IO请求就处理。
一个线程,处理多个读写请求。
有三大和部分:通道,缓冲区,选择器
缓冲区:是一块内存区,底层是一个数组。本质上是一块可以写入数据,然后可以从中读取数据的内存,这块内存被包装成NIO Buffer对象。
并提供了一组方法,用来方便的访问该块内存,相比较直接对数组操作,Buff API更加容易操作和管理
通道: java NIO类似流,但又有些不同:即可以从通道读取数据,又可以写数据到通道,但流只能写或者只能读。
通道可以非阻塞读取和写入通道,通道可以支持读取或写入缓冲区,也支持异步读写。
选择器:选择器负责,检查一个或多个通道,他负责轮回通道,检测里面是否存在数据。选择来进行处理。
每一个通道对应一个缓冲区,一个线程对应选择器,一个选择器对应多个通道
程序切换到哪个通道是由事件决定的,选择器会根据不同事件,在各个通道上切换。
使一个线程从某个通道发送请求或者读取数据,但是他仅能得到目前可用的数据,如果目前没有数据可用时。
就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。
让accept()和read()不阻塞
实现单线程并发的问题
因为线程在等待资源,等待客户端链接,等待客户端输入数据
适用场景:适合比如聊天服务器,连接数量比较多,且连接时间比较短的架构
AIO模型(异步非阻塞)
当进行读写操作时,只需要直接调用API的read或write方法即可。这两种方法都为异步的
NIO2.0 异步非阻塞,服务器实现模式为一个有效请求一个线程。客户端的IO请求都是有OS先完成了再通知服务器应用去启动线程进行处理。
适用场景: 比较使用连接数量比较多,连接时间比较长的服务器架构(1.7之后才支持)