Java中的五种IO模型

同步与异步 阻塞和非阻塞
  1. 同步与异步

    同步与异步其实是指对CPU时间片的利用,主要是看请求发起方,对消息的获取是主动发起的还是被动通知的.

    • 如果是主动发起的,一直在等待应答结果(同步阻塞),或者可以处理其他事情,但要不断轮询查看发起的请求是否有应答结果(同步非阻塞)
    • 如果是由服务方通知的也就是请求方发出请求后,要么一直等待通知(异步阻塞),要么先去干自己的事情(异步非阻塞),当事情处理完成后,服务方会主动通知请求方,它的请求已经完成,这就是异步,异步通知的方式有状态改变,消息通知,或者回调函数来完成,大多数时候采用的都是回调函数
  2. 阻塞与非阻塞

    阻塞与非阻塞通常是指的针对IO的操作,简单的说,就是我们调用了一个函数后,再等待这个函数返回结果之前,当前的线程是处于挂起状态,还是运行状态,如果是挂起状态,就意味着当前线程什么都不能干,就等着获取结果,这就是同步阻塞,如果仍然是运行状态,就意味着当前线程是可以继续处理其他任务的,就是非阻塞状态

进程和线程的区别
  1. 进程是系统进行资源分配和调度的一个独立单位,进程有独立的地址空间
  2. 线程 是进程的一个实体,是CPU调度和分配的基本单位,它是比进程更小的能独立运行的基本单位,
  3. 一个程序至少有一个进程,一个进程至少有一个线程

线程执行开销小,但不利于资源的管理和保护,而进程正相反

IO模型

在网络环境下,通俗的讲,将IO分为两步: 第一步是等待 ; 第二步是数据搬迁.

如果想提高IO效率,主要就是降低等待时间,因此发展出来了五种IO模型,分别是阻塞IO,非阻塞IO,多路复用IO,信号驱动IO,异步IO

其中前四种都是同步IO,只有最后一种才是异步IO

  • 阻塞IO

    用户进程向系统内核发送请求后,在等待系统内核处理数据的这段时间,线程处于挂起状态,这时当前线程什么都不能干,就等待结果.当数据准备好了后,系统内核,将数据拷贝到用户内存,然后返回结果,用户进程才解决阻塞状态,重新运行起来

特点在IO执行的两个阶段(等待数据和拷贝数据)都被阻塞
典型应用阻塞Socket, Java BIO
优点进程阻塞挂起不消耗CPU资源,及时响应每个操作. 实现难度低,开发应用较容易,适合并发小的网络应用
缺点不适合并发量大的应用,因为一个请求IO会阻塞进程 需要为每一个请求分配一个处理进程(线程)以及时间响应,系统开销大
  • 非阻塞IO

    当用户进程发出请求后,如果内核中的数据还没准备好,那么他不会阻塞用户进程,而是立刻返回一个error,当用户进程判断结果是一个error时,他就知道数据还没准备好,于是它可以再次发送请求 ,就这样不停的轮询直到内核数据准备好了,并且再次收到了用户进程的请求,那么就会把数据拷贝到用户内存,然后返回

    在等待系统内核处理数据的时候,非阻塞IO会不停的轮询查看发起的请求是否有应答结果,但可以去处理其他事情

特点用户进程需要不断的主动询问内核(Kernel)数据准备好了没
典型应用Socket设置NON_BlOCK
优点实现难度低,开发应用相对阻塞IO模型较难
缺点进程轮询(重复)调用,消耗CPU的资源 适合并发量较小且不需要及时响应的网络应用开发
  • 多路复用IO模型

    多个进程的IO可以注册到一个复用器(Selector)上,当用户进程调用该Selector,Selector会监听注册进来的所有IO,如果Selector监听所有的IO,在内核上缓冲区上都没有可读的数据时,select调用就会返回,而后select调用进程可以自己或者通知注册到Selector上面的IO再次发起读取IO,读取内核中准备好的数据,多个进程注册IO后,只有一个select调用进程被阻塞

特点对于每一个Socket,一般都设置成非阻塞,但是整个用户的进程其实一直都是被阻塞的,只不过进程是被select函数阻塞,而不是被SocketIO阻塞
典型引用Java NIO , Nginx,
优点专一进程解决多个进程IO的阻塞问题,性能好,Reactor模式 适合高并发服务应用开发,一个进程/线程响应多个请求
缺点实现和开发应用难度较大
  • 信号驱动IO

    用户进程预先告知内核,向内核注册一个信号处理函数,然后用户进程返回不阻塞,当内核数据就绪时会发送一个信号给进程,用户进程便在信号处理函数中调用IO读取数据

特点并不符合异步IO的要求,只能算是伪异步,并且在实际中并不常用
典型应用应用场景较少
优点应用场景少,不做总结
缺点实现和开发应用难度大
  • 异步IO

    用户进程发起aio_read操作后,给内核传递与read相同的描述符,缓冲区指针,缓冲区大小三个参数及文件偏移,告诉内核整个操作完成时如何通知,用户进程立刻就可以开始做其他的事情,从内核上看,当它收到一个aio_read之后,就会立刻返回,不会对用户进程造成阻塞,内核会等数据准备完成后,然后将数据拷贝到用户内存上,当这一切都完成之后,内核会给用户进程发送一个信号,告诉它aio_read操作完成

特点真正实现了异步IO,是五种IO模型中唯一的异步模型
典型应用Java7 AIO ,高性能服务器应用
优点不阻塞,数据一步到位,采用Proactor模式,非常适合高性能,高并发应用
缺点需要操作系统的底层支持,Linux2.5内核首现,Linux2.6产品的内核标准特性,实现和开发应用难度大
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值