JAVA中的IO

基础概念

IO操作的两个阶段

对于一个网络IO(这里我们以read举例),它会涉及到两个系统对象:

  1. 一个是调用这个IO的过程process(orthread)
  2. 另一个就是系统内核(kernel)

当一个read操作发生时,它会经历两个阶段:

  1. 等待数据准备(Waitingfor the data to be ready)
  2. 将数据从内核拷贝到进程中(Copyingthe data from the kernel to the process)

记住这两点很重要,因为这些IO Model的区别就是在两个阶段上各有不同的情况。

是否阻塞说的是第一个阶段,即等待数据准备阶段是否会阻塞,

而是否同步说的是第二阶段,即将数据从内核拷贝到进程这个真实的IO Operation操作阶段是否阻塞。

如下图所示:

这里写图片描述

阻塞

内核在检查数据未就绪时,会一直等待,直到数据就绪

这里写图片描述

当用户进程调用了recvfrom这个系统调用,内核就开始了IO的第一个阶段:准备数据。对于网络IO来说,很多时候数据在一开始还没有到达(比如,还没有收到一个完整的UDP包),这个时候内核就要等待足够的数据到来。而在用户进程这边,整个进程会被阻塞。当内核一直等到数据准备好了,它就会将数据从内核中拷贝到用户内存,然后内核返回结果,用户进程才解除block的状态,重新运行起来。

所以,blocking IO的特点就是在IO执行的两个阶段都被block了。

非阻塞

如果数据没有就绪,则会返回一个标志信息告知用户线程当前要读的数据没有就绪

这里写图片描述

从图中可以看出,当用户进程发出read操作时,如果内核中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户进程角度讲,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。一旦内核中的数据准备好了,并且又再次收到了用户进程的systemcall,那么它马上就将数据拷贝到了用户内存,然后返回。

所以,用户进程其实是需要不断的主动询问内核数据好了没有。

所以,non-blocking IO的特点就是在IO执行的第一阶段不阻塞,若没准备好即可返回,但是在第二阶段即将数据从内核拷贝到进程这个真实的IO Operation操作阶段会阻塞。

阻塞和非阻塞的区别

这里写图片描述

它们的区别在于I/O的第一阶段,阻塞是选择等待,非阻塞是返回一个标志信息

那么非阻塞I/O的优势在哪里呢?

使用阻塞I/O处理网络连接时,有10000个连接就要开10000个线程,无论有没有数据到来,处理某一连接的线程必须“忠实地阻塞”。
而非阻塞I/O就不需要这样,它可以维护一个1000个线程的线程池,当有数据就绪时,启动一个线程去接受数据,当没有数据时,线程不需要等待,直接就可以回到池中,等待被调度到去接受其它连接。

因此非阻塞I/O非常适合连接多但传输的数据内容不大的情况,
如果连接少数据多,阻塞I/O更容易编程

同步

当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程

异步

只有IO请求操作的发出是由用户线程来进行的,内核自动完成检查数据是否就绪和将数据拷贝到用户空间的过程,然后发送通知告知用户线程IO操作已经完成。

这里写图片描述

用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从内核的角度,当它受到一个asynchronousread之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,内核会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,内核会给用户进程发送一个signal,告诉它read操作完成了。

所以异步IO的特点是,在IO操作的两个阶段都不会阻塞,而是全权交给操作系统内核来完成,而内核完成后通过信号来通知用户进程即可。

同步和异步区别

也许会奇怪在这里说到同步I/O会阻塞,异步I/O不会阻塞,那么是不是意味着同I/O必然是阻塞I/O呢?

其实不然,同步/异步I/O阻塞的地方和之前说的阻塞/非阻塞IO阻塞的地方不一样。同步/异步I/O阻塞的地方是用户或内核需要轮询数据是否就绪,
而阻塞/非阻塞IO是阻塞在数据未就绪的状态下。

简单点说:
同步与异步是针对应用程序与内核的交互而言的。
同步过程中进程触发IO操作并等待或者轮询的去查看IO操作是否完成。
异步过程中进程触发IO操作以后,直接返回,做自己的事情,IO交给内核来处理,完成后内核通知进程IO完成。

同步阻塞

将数据从内核拷贝到进程中会阻塞,等待数据准备会阻塞

同步非阻塞

将数据从内核拷贝到进程中会阻塞,等待数据准备不会阻塞

异步阻塞

将数据从内核拷贝到进程中不会阻塞,等待数据准备会阻塞

异步非阻塞

将数据从内核拷贝到进程中不会阻塞,等待数据准备不会阻塞

BIO
请求数与处理线程比为 ====> m :m

伪异步IO
请求数与处理线程比为 ====> m :n

NIO
请求数与处理线程比为 ====> m :1

AIO
请求数与处理线程比为 ====> m :0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值