五种IO模型
阻塞IO模型
Java中进行输入/输出时,多数情况都直接使用java.io中的类,这些类都属于阻塞IO模型,也称为传统IO。这种IO模型在线程发出IO请求后,内核会去查看数据是否就绪,如果数据未就绪,则会处于阻塞状态,并交出CPU。
非阻塞IO模型
当执行IO操作时,并不交出CPU,而是不断询问数据是否准备就绪,典型的非阻塞IO实现就是使用循环来询问数据准备状态,这样会造成CPU占用率过高。
多路复用IO模型
和非阻塞IO模型相比,在多路复用IO模型中,不需要时刻占用CPU进行监控,而使用单个线程轮询多个socket状态,只有当socket真正有读写事件时才真正调用实际IO操作,也就是通过单个线程达到多路复用的目的,不需要时刻监控,达到减少资源占用的目的。因此,多路复用IO适用于连接数较多的情况。
但由于多路复用IO是采用轮询的方式,因此当某一时间响应时间过长时,会导致其他事件不能及时处理。
Java NIO中就使用了多路复用IO模型,使用Selector监听多个Channel。
在Java NIO中,多路复用仅适用于套接字Channel,不适用于处理文件的FileChannel
信号驱动IO模型
用户线程发起IO请求时,给socket注册信号函数,同时线程会继续执行下面的操作,当数据就绪时会发送信号给用户线程,用户线程接到信号后执行IO操作。
异步IO模型
用户线程发起IO请求后,不必等待可直接执行之后的其他操作,IO请求全部发送给内核,内核收到请求后通知用户线程已经成功发起了请求,之后不会阻塞用户线程。内核处理完IO请求后,会将处理后的数据拷贝到用户线程,再通知用户线程请求已经完成。也就是说,用户线程并不直接处理IO请求,而由内核来完成IO请求,这样避免了线程的切换和阻塞,加快了IO处理效率。