> 文章列表 > 【2023-04-22】 io操作和java io

【2023-04-22】 io操作和java io

【2023-04-22】 io操作和java io

用户操作io时,会向操作系统调用read,write函数

同步阻塞io:用户线程会阻塞,等会内核完成io返回有用户线程才会继续执行

同步非阻塞io:用户在做io请求时,不管有没有完成都立即返回,如果返回结果告知数据未准备好,那么可以立即再次请求,直到io完成。虽然不会阻塞,但是会一直循环请求,消耗CPU的资源。

同步非阻塞io-io多路复用:前面提到线程会一直循环请求,而io多路复用就是让线程避免轮询请求。实现io多路复用的三种方式:select,poll,epoll。

1)select:进行io操作时会维护一个fdset文件描述符,如果有可写,可读,或异常的状态,会更新到这个fdset,select会阻塞住监视这个fdset,等有数据、可读、可写、出异常或超时就会返回,返回后会遍历整个fdset,找到就绪的fd,进行io操作。这个fdset底层是一个数组维护,默认是1024。

​ 缺点:1.由于是采用轮询方式全盘扫描,会随着文件描述符 FD 数量增多而性能下降。2.每次调用 select(),都需要把 fd 集合从用户态拷贝到内核态,并进行遍历(消息传递都是从内核到用户空间)。3.单个进程打开的 FD 是有限制(通过FD_SETSIZE设置)的,默认是 1024 个,可修改宏定义,但是效率仍然慢。

2)poll:基本原理和select一样,fdset使用链表做存储方式,没有最大数量限制。

​ 缺点同select第一点和第二点。

3)epoll:epoll对select和poll进行了优化,只在内核中保存fd,用户只需传入修改的部分即可,内核也不在通过轮询的方式进行寻找就绪的客户端,,而是使用事件通知的形式通知已经就绪的客户端,内核就绪的io的唯一标识传递给用户,用户也不用遍历fdset。

java io

Java BIO:服务器实现模式为一个连接一个线程,即用户端有连接请求时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的线程开销。

Java NIO:服务器实现模式为一个线程处理多个请求连接,即客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询连接有io请求就进行处理。

Java AIO:服务器实现模式为一个有效请求一个线程,客户端的io请求都是由内核完成了再通知服务器应用去启动线程进行处理,一般适用于连接数较多且连接市场较长的应用