java中的io复用,浅谈IO丶Java教程网-IT开发者们的技术天堂

IO读写的基本原理

程序进行IO读写依赖于操作系统底层的IO读写,主要为read&write两大系统调用。应用程序无论是调用操作系统的read还是write,都会涉及到缓冲区。具体来说,调用操作系统的read,是把数据从内核缓冲区复制到进程缓冲区 ;而write调用,是把数据从进程缓冲区复制到内核缓冲区。(上层程序的io操作,实际上并没有物理设备级别的读写,而是缓存的复制。这项底层的读写交换,是由操作系统内核(Kernel)来完成的)

主要四种方式的IO模型

同步阻塞IO(BIO)

阻塞IO指的是内核IO操作彻底完完成后,才返回用户空间执行用户的操作。阻塞指的是用户空间程序的执行状态

阻塞期间用户线程一直在等待,基本不会占用CPU资源。

同步非阻塞IO(NIO)

用户空间的程序不需要等待内核IO操作彻底完成,可以立即返回用户空间执行用户的操作。内核会立即返回给用户一个状态值。

应用程序的线程需要不断地进行IO系统调用,轮询数据是否已经准备好,如果没有准备好,就继续轮询,直到完成IO系统调用为止

在NIO模型中,应用程序一旦开始IO系统调用,会出现以下两种情况

1. 在内核缓冲区中没有数据的情况下,系统调用会立即返回,返回一个调用失败的信息。

2. 在内核缓冲区中有数据的情况下,是阻塞的,直到数据从内核缓冲复制到用户进程缓冲。复制完成后,系统调用返回成功,应用进程开始处理用户空间的缓存数据。

总体来说,在高并发应用场景下,同步非阻塞IO也是不可用的。一般Web服务器不使用这种IO模型。这种IO模型一般很少直接使用,而是在其他IO模型中使用非阻塞IO这一特性。在Java的实际开发中,也不会涉及这种IO模型。

IO多路复用

IO多路复用可以解决非阻塞IO模型中存在的轮询等待问题。在IO多路复用模型中,引入一种新的系统调用(Linux中,为select/epoll),查询IO的就绪状态。通过该调用,一个进程可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓存区可读/可写),内核就能够将就绪的装填返回给应用程序。随后,应用程序根据就绪的状态,进行相应IO系统调用。

优点: 与一个线程维护一个连接的阻塞IO模式相比,使用select/epoll的最大优势在于,一个选择器查询线程可以同时处理成千上万个连接(Connection)。系统不必创建大量的线程,也不必维护这些线程,从而大大减小了系统的开销。Java语言的NIO(New IO)技术,使用的就是IO多路复用模型。在Linux系统上,使用的是epoll系统调用。

缺点: 本质上,select/epoll系统调用是阻塞式的,属于同步IO。都需要在读写事件就绪后,由系统调用本身负责进行读写,也就是说这个读写过程是阻塞的。

举个栗子——发起一个多路复用IO的read读操作的系统调用

1. 选择注册器。将read操作的目标socket网络连接,提前注册到select/epoll选择器中

2. 就绪状态的轮寻。通过选择器的查询方法,查询注册过的所有Socket连接的就绪状态,通过轮询的系统调用,内核会返回一个就绪的socket列表

3. 当用户线程调用了select查询方法,那么整个线程会被阻塞掉

4. 用户线程获得了就绪状态的列表后,发起read调用,用户线程阻塞,内核开始复制数据,将数据从内核缓冲区复制到进程缓冲区

5. 复制完成后,内核返回结果,用户线程才会接触阻塞的状态,用户线程读取到数据,继续执行!

异步IO

用户线程通过系统调用,先向内核注册某个IO操作。内核在整个IO操作完成后,通知用户程序,用户执行后续的业务操作。

异步IO是真正的异步输入输出,它的吞吐量高于IO多路复用模型的吞吐量。但是它依赖操作系统的实现,比如Linux的异步IO模型目前并不完善,在性能上没有优势。所以,大名鼎鼎的Netty框架,使用的就是IO多路复用模型,而不是异步IO模型。

流程

1 当用户线程发起了read系统调用,立刻就可以开始做其他事情,用户线程不阻塞。

2 内核开始IO的第一阶段:准备数据。等到数据准备好了,内核就会将数据从内核缓存区复制到用户缓存区。

3 内核会给用户线程发送一个信号,或者回调用户线程注册的回调接口,告诉用户线程read操作完成了。

4 用户线程读取用户缓存区的数据,完成后续的业务操作。

参考

《Netty、Redis、Zookeeper高并发实战》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值