BIO、NIO、AIO区别

一、BIO、NIO、AIO特点

1、BIO的特点就是每次一个客户端接入,都要在服务端创建一个线程来服务于这个客户端,所以如果有很多个客户端,就会对应成千上万个服务端线程,这会导致服务端负载过高,甚至卡死。

2、NIO是同步非阻塞io,客户端和服务器端通过channel(通道)通讯,实现了多路复用

  • 1.一个客户端会对应一个channel,然后多路复用器selector会轮询channel
  • 2. 然后当有请求过来的时候,selector才会去创建工作线程与buffer,
  • 3. 工作线程会通过buffer从channel中读取请求并进行处理
  • 4. 然后处理完成后再通过buffer将数据返回给channel,当请求读写完成后会释放这个线程BIO、NIO、AIO区别_第1张图片

3、AIO是NIO的升级,实现了异步非阻塞,异步IO的操作基于事件和回调机制 

二、buffer、channel、selector相关概念

buffer实际上是一个容器,内部通过一个连续的字节数组存储I/O上的数据,在nio中,channel在文件、网络上对数据的读取或是写入都必须通过buffer

selector用于检测在多个注册的channel上是否有I/O事件发生,并对检查到的I/O事件进行相应的相应和处理,因此通过一个selector线程可以实现对多个channel的管理,而不必 每个线程都创建一个线程,避免线程资源的浪费和多线程之间的上下文切换导致的开销。seletor只在channel上有读写事件发生时候,才会调用I/O的函数进行读写操作,可极大的减少系统开销,提高系统的并发量

三、select、poll、epoll

  • fd是什么? fd既file descriptor-文件描述符。Java中用对象代表输入输出流等...在Linux系统中不是面向对象的,是一切皆文件的,拿文件来代表输入输出流
  • select:它的模式是这样的:程序端每次把文件描述符集合交给select的系统调用,select遍历每个文件描述符后返回那些可以操作的文件描述符,然后程序再次遍历可以操作的文件描述符进行读写。
  • poll:以链表来存储文件描述符集合
  • ​epoll:内核通过mmap实现共享空间,用户态和内核态有一个空间是共享的,文件描述符fd存在共享空间实现用户态和内核态共享。epoll里面有三个调用,用户空间先epoll_create准备一个共享空间mmap,里面维护一个红黑树,内核态将连接注册进红黑树,epoll_ctl写入。当有数据准备好了,调用epoll_wait中断阻塞,取链表fd,再单独调用read。mmap应用:kafka实现数据通过socket存到服务器文件上的过程也是mmap。

四、缓存I/O、内存映射文件和零拷贝

  • 用户态:用户程序运行在用户态,用户态下有许多限制。比如无法直接操作硬件、创建和切换线程、开辟内存等操作(安全),这些操作都需要通过内核态完成
  • 内核态:可直接操作系统硬件资源等,用户态可通过系统调用转换为用户态。比如用户态的io操作、切换线程都是通过系统调用进入内核态通过kernel(内核)完成的
  • 对于缓存I/O,一个读操作会有3次数据拷贝,磁盘》内核缓存区》用户缓存区》应用程序内存
  • 对于缓存I/O,一个写操作会有3次数据拷贝,应用程序内存》用户缓存区》内核缓存区》磁盘

内存映射文件:当用户不再有物理内存,直接拿应用程序的逻辑内存地址映射到Linux操作系统的内核缓冲区,应用程序虽然读写的是自己的内存,但是这个内存只是一个逻辑地址,实际读写的是内核缓冲区

读:磁盘》内核缓冲区

写: 内核缓冲区》磁盘

你可能感兴趣的:(面试题,java知识点,nio,java,服务器)