1-3 IO-BIO和NIO和AIO-Select和epoll多路复用

上一篇:
1-2 map和list和set-ThreadLocal-finally-finalize

这里是easy的java基础面试
下面是总的阅览:

java基础
java集合
JVM
多线程
mysql_数据库
计算机网络
nosql_redis
设计模式
操作系统
消息中间件activeMq
SSM框架面试题
服务中间件Dubbo

目录

1-IO

IO是什么?输入输出流啊
先让我们来看一下同步异步,阻塞和非阻塞吧。

1-1-同步与异步

同步: 同步就是发起一个调用后,被调用者未处理完请求前,调用不返回。
异步: 异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果。此时我们可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者返回结果。

1-2-阻塞和非阻塞

阻塞: 阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程被挂起,无法从事其他任务,只有当前条件就绪才能继续。
非阻塞: 非阻塞就是发起一个请求,调用者不用一直等待结果返回,可以先去干其他事情。

注意: 同步是一个过程,阻塞是线程的一种状态。比如 servlet3.0 异步io 业务线程和tomcat工作线程

2-BIO-NIO-AIO介绍

2-1-BIO

同步并阻塞。服务器实现模式为一个连接一个线程,即客户端链接请求时,服务端就需要启动一个线程进行处理,如果这个链接不做任何事情会造成不必要的线程开销,当然可以通过线程池机制来改善。

特点: BIO方式适用于连接数目较小固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择,但程序简单容易理解

2-2-NIO

同步非阻塞。 服务器实现模式为一个请求一个线程,即客户端发送的连接请求都会注册多路复用器上,多路复用器轮训到连接有I/O 请求时,才会启动一个线程进行处理。

特点:NIO方式适用于连接数目多链接比较短(轻操作)的架构,比如聊天服务器并发局限于应用中,编程比较复杂,JDK1.4开始支持。

2-3-AIO

异步非阻塞。服务器实现模式为一个有效请求一个线程,客户端的I/O 请求都是由 os 先完成了再通知服务器应用去启动线程进行处理。

特点: AIO适用于连接数目较多连接比较长(重操作)的架构。比如图像服务器,充分调用os参与并发操作,编程比较复杂JDK1.7才开始支持。

3-Select和epoll多路复用

3-1-多路复用的原理

多路复用机制是同步非阻塞的IO,即synchronous I/O Multiplesing,它是利用单独的线程(内核级) 统一监测所有Socket, 一旦某个Socket 有I/O 数据,则启动相应Application 处理,在Select 和 poll利用轮询Socket 句柄的方式来实现监测 Socket中是否有 I/O 数据到达。这种方式有开销。

epoll则改进了这种方式,利用底层notify, 即Reactor 方式来监测,Java NIO也是采用这种机制。

注意:其实多路复用还是在有阻塞的(这个阻塞并非以上定义的阻塞,这里指Socket 无I/O 数据时,还是被wait,此外当使用Select 函数copy I/O数据入Application Buffer时,Application 还是被阻塞的 )。

3-2-select和epoll的区别

  1. 每次调用Select, 都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。
  2. 同时每次调用Select 都需要在内核态遍历传递进来的所有fd,这个开销在fd很多的时候会很大。
  3. select 支持的文件描述符数量太小了,默认是1024。

poll: 它没有最大链接数的限制,是因为它是基于链表来存储的,但是同样有一个缺点,大量的fd数组被复制于用户态和内核态空间之间。而不管这样是否有意义。

  1. epoll 为每个fd指定一个回调函数,当设备准备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数。(注意: 等待队列是在内核态中。)
  2. epoll所支持的fd上限是最大可以打开的数目。

fd: long型的数组,每个元素都可以打开文件句柄(Socket / 通道 )

3-3-NIO原理

首先,我们必须要了解三个概念缓冲区(Buffer), 通道(channel),选择器(Selector)。
在这里插入图片描述

3-3-1读

  1. 从FileInputStream, 获取channel
  2. 创建Buffer
  3. 将数据从Channel读取到Buffer中。

flip方法会将Buffer 从写模式转变为模式。调用flip方法之后,方法会将position 设置为0,并将limit设置为之前的position。

3-3-2写

  1. 从FileOutputstream,绑定文件并选择Channel
  2. 创建Buffer
  3. 从Buffer读取数据到channel中,此时刷新到文件中。

3-3-3读写方式

从buffer读取数据两种:
从bufer读取数据到channel
使用get() 方法从buffer 中拿去数据

写数据进入buffer两种:
从channel写入到buffer
通过buffer的put方法写到buffer内。

3-3-4为什么用Selector和注意?

仅仅使用单个线程来处理多个channels的好处是: 只需要更少的线程来处理通道、

与Selector一起使用时,channel必须处于非阻塞模式下。这意味着不能讲filechannel与selector一起使用,因为fileChannel不能切换到非阻塞模式下。而套接字通道可以。

3-3-5监听的四种事件

connect,accept ,read,write
一旦调用了Selector的Select()方法,并且返回值表名有一个或者多个通道就绪了,然后可以通过调用selector的selectkeys() 方法,访问已选择键集(selected key set)中的就绪通道。

4-Java中NIO与IO区别

IO 是面向流的,而NIO是面向缓冲区的。

IO的各种流是阻塞的,当一个线程调用write或者read() 。此线程阻塞,直到有一些数据读取。NIO是非阻塞模式,使用一个线程从某个通道发送读取数据,但它仅能得到当前可用的数据,如果当前无可用数据时,就什么都不会获取。

NIO的选择器允许一个单独线程监视多个输入通道。可进行读写,通道是双向的,但流的读写是单向的

4-补充面试io知识

NIO中的heapByteBuffer 和 内存中的directByteBuffer

种类heapByteBufferdirectByteBuffer
在哪JVM堆上os内存中
本质是啥数组 用类封装,维护多个索引os内维护一个引用address指向数据从而操作数据
优点速度快,更容易回收跟外设IO打交道,外设读取JVM数据,省去了先去jvm找内存块,再去内存读取这两个步骤。变为直接读取内存数据。

下一篇:
1-4 异常-接口和抽象类-socket通信原理-Runtime类-泛型-字节流和字符流

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下次遇见说你好

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值