JAVA IO

#JAVA IO

IO基础知识

I(Input 把持久设备上的数据读取到内存中的这个动作称为输入(读)Input操作)
O(Output 把内存中的数据存储到持久化设备上这个动作称为输出(写)Output操作)
我们把这两种操作成为IO.以输入为例,我们可以粗略画个草图
在这里插入图片描述
IO操作有多种方式,不同的实现方式性能上面表现也不一样。我们从内存复制,阻塞时间来分析不同的IO模型的差异,可能更好理解。
常见IO模型分类及对比:
在这里插入图片描述

我们按照次序从左到右 来介绍这几个IO模型:

首先我们要知道一个基础共识:

所有的系统I/O都分为两个阶段:等待就绪和操作。举例来说,读函数,分为等待系统可读和真正的读;同理,写函数分为等待网卡可以写和真正的写。等待就绪的阻塞是不使用CPU的,是在“空等”;而真正的读写操作的阻塞是使用CPU的,真正在"干活",而且这个过程非常快,属于memory copy,带宽通常在1GB/s级别以上,可以理解为基本不耗时。
通俗一点:I/O的阻塞有两阶段,一个是等待可以操作的阻塞(不消耗CPU),一个是真正执行的阻塞(CPU干活);而且一般前者阻塞时间往往大于后者

  • 阻塞I/O:传统BIO模型,线程会一直阻塞至数据可以读,数据完成读取操作之后得到返回
  • 非阻塞I/O:线程第一次调用,发现数据不可读,返回失败,通过死循环,不断轮训读取状态;数据可读时,阻塞在真正的读取操作上
  • I/O复用:Java NIO 就是多路复用IO模型。单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力。我们发现“可以读”这里的阻塞是我们最大的难题。干脆就设置一个线程(进程)来处理可以读的逻辑,当很多连接进来时,监听进程如果发现有可以读的事件,就会通知对应的连接处理。他的本质是用更少的资源完成更多的事。后面我们也会重点介绍这个模型。
    信号驱动I/O:信号驱动IO是利用信号机制,让内核告知应用程序文件描述符的相关事件。这里我们让内核来通知我们什么时候可以读 什么时候读完了,通过信号机制。但信号驱动IO在网络编程的时候通常很少用到,因为在网络环境中,和socket相关的读写事件太多了,但我们没办法在SIGIO对应的信号处理函数中区分上述不同的事件。
    比如下面的事件都会导致SIGIO信号的产生:
    TCP连接建立
    一方断开TCP连接请求
    断开TCP连接请求完成
    TCP连接半关闭
    数据到达TCP socket
    数据已经发送出去(如:写buffer有空余空间)
  • 异步IO(AIO):用户进程发起read操作之后,立刻就可以开始去做其它的事。而另一方面,从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。
    调用者不在阻塞!现在我只需要发起一个I/O操作,这个操作会立即返回 不会阻塞,当操作完成,操作系统会通过回调的方式通知我。实际上AIO的应用场景并不多,linux内核2.6版本才开始引入,来看看一张内核的原理图:
    在这里插入图片描述

进阶

所谓的I/O 就是计算机内存与外部设备之间拷贝数据的过程。

Java NIO

展望

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值