>>分享流行的Java框架以及开源软件,对孙卫琴的《精通Spring:Java Web开发技术详解》提供技术支持 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 14275 个阅读者 刷新本主题
 * 贴子主题:  NIO的几道常见面试题 回复文章 点赞(0)  收藏  
作者:javathinker    发表时间:2021-06-24 07:27:01     消息  查看  搜索  好友  复制  引用

1.叙述BIO、NIO和AIO概念

  •   BIO:同步并阻塞,服务器的实现模式是一个连接一个线程,这样的模式很明显的一个缺陷是:由于客户端连接数与服务器线程数成正比关系,可能造成不必要的线程开销,严重的还将导致服务器内存溢出。当然,这种情况可以通过线程池机制改善,但并不能从本质上消除这个弊端。
  •   NIO:在JDK1.4以前,Java的IO模型一直是BIO,但从JDK1.4开始,JDK引入的新的IO模型NIO,它是同步非阻塞的。而服务器的实现模式是多个请求一个线程,即请求会注册到多路复用器Selector上,多路复用器轮询到连接有IO请求时才启动一个线程处理。
  •   AIO:JDK1.7发布了NIO2.0,这就是真正意义上的异步非阻塞,服务器的实现模式为多个有效请求一个线程,客户端的IO请求都是由OS先完成再通知服务器应用去启动线程处理(回调)。

2.NIO和IO的主要区别?

  • 面向流与面向缓冲

    Java IO和NIO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的。 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
  • 阻塞与非阻塞IO

    Java IO的各种流是阻塞的。这意味着,当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入。该线程在此期间不能再干任何事情了。Java NIO的非阻塞模式,使一个线程从某通道发送请求读取数据,但是它仅能得到目前可用的数据,如果目前没有数据可用时,就什么都不会获取,而不是保持线程阻塞,所以直至数据变的可以读取之前,该线程可以继续做其他的事情。 非阻塞写也是如此。一个线程请求写入一些数据到某通道,但不需要等待它完全写入,这个线程同时可以去做别的事情。 线程通常将非阻塞IO的空闲时间用于在其它通道上执行IO操作,所以一个单独的线程现在可以管理多个输入和输出通道(channel)。
  • 选择器(Selectors)

    Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道:这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。
NIO提供了与标准IO不同的IO工作方式:

Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

Asynchronous IO(异步IO):Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。

Selectors(选择器):Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

3.NIO的核心组件有哪些?

Channel buffer selector

Channel和流有点类似。通过Channel,我们即可以从Channel把数据写到Buffer中,也可以把数据冲Buffer写入到Channel,每个channel对应一个buffer缓冲区,channel会注册到selector。selector根据channel上发生的读写事件,将请求交由某个空闲的线程处理,selector对应一个或多个线程,channnel和buffer是可读可写的。

4.select、poll和epoll有什么区别?

他们是NIO多路复用的三种实现机制,是有lunix系统提供。

-select:无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作,会维护一个文件描述符FD的集合fd_set,将fd_set从用户空间复制到内核空间。x86 fd_set是数组结构

-poll:与select机制相似,fd_set结构进行优化,突破操作系统限制,pollfd代替fd_set,链表结构

-epoll:不再扫描所以fd,只将用户关心的事件放在内核的一个事件表中,减少用户空间和内核空间的数据拷贝。epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。


----------------------------
原文链接:https://www.jianshu.com/p/c52ee1727286

程序猿的技术大观园:www.javathinker.net



[这个贴子最后由 flybird 在 2021-06-24 10:39:43 重新编辑]
  Java面向对象编程-->面向对象开发方法概述之开发思想(上)
  JavaWeb开发-->开发JavaMail Web应用
  JSP与Hibernate开发-->域对象在持久化层的四种状态
  Java网络编程-->RMI框架
  精通Spring-->Vue组件开发高级技术
  Vue3开发-->创建综合购物网站应用
  10分钟认识RocketMQ!想进阿里连这个都不会?
  面试官问什么是Spring循环依赖,该如何回答?
  Mybatis Plus 多租户架构(Multi-tenancy)实现
  Spring API中JAVA反射—工具类ReflectionUtils
  Spring事务容易掉入的坑
  使用Spring MVC多次读取请求Request Body的内容
  微服务的拆分方式
  @Resource注解的用法
  深入Redis客户端(redis客户端属性、redis缓冲区、关闭redis客...
  Redis用作消息队列
  理解 RESTful 风格的 API
  Spring+JPA+ehcache开启二级本地缓存
  3分钟让你明白JSON是什么
  深入理解Mybatis一级缓存
  Gradle入门
  更多...
 IPIP: 已设置保密
楼主      
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。