🦊 Java
1、Java基础
1.1 StringBuffer和StringBuilder的区别
1.2 ConcurrentHashMap和TreeMap实现原理
1.3 ArrayList和LinkedList实现原理
1.4 HashSet和TreeSet实现原理
1.5 深拷贝与浅拷贝
1.6 抽象类与接口
2、Java多线程
2.1 并发编程的三大特性
2.2 指令重排
2.3 Volatile原理
2.4 CAS原理
2.5 Java的4种引用级别
2.6 Java中的锁
2.7 Synchronized实现原理
2.8 线程池实现原理
2.9 AQS
2.10 创建线程的方式
2.11 ThreadLocal原理
3、JVM
3.1 判断对象是否存活的方法
3.2 JVM内存结构
3.3 常见的垃圾收集算法有哪些
3.4 指针碰撞和空闲列表
3.5 常见的垃圾收集器有哪些
3.6 内存溢出与内存泄漏的区别
3.7 常用的JVM启动参数有哪些
3.8 反射机制
4、NIO
4.1 概述
5、Spring
5.1 Spring IOC
5.2 Spring AOP
6、SpringBoot
6.1 SpringBoot、SpringCloud的联系与区别
-
+
游客
注册
登录
概述
## 1 简介 1. NIO 中的 N 可以理解为 Non-Blocking,是**一种同步非阻塞的 I/O 模型**,**在 JDK 1.4 中引入了 NIO 框架**,**对应于 `java.nio` 包**,**提供了 `Channel`、`Selector`、`Buffer` 等抽象**。 2. 他**支持面向缓冲的**、**基于通道的 I/O 操作方法**,**提供了与传统 I/O 模型中的 `Socket` 和 `ServerSocket` 相对应的 `SocketChannel` 和 `ServerSocketChannel` 两种不同的套接字通道实现**,这两种通道**都支持阻塞和非阻塞两种模式**: 1. 阻塞模式就像传统中的支持一样,比较**简单**,但是**性能和可靠性都不好**,一般**用于低负载**、**低并发的应用程序**,以此来**提升开发速度和可维护性**。 2. 非阻塞模式正好与之相反,一般**用于高负载**、**高并发的**(网络)**应用**,以此来**提升高性能和可靠性**。 ## 2 BIO、NIO、AIO 的区别 > 底层原理可参考[五种 IO 模型](https://notebook.ricear.com/project-26/doc-335/#3-%E4%BA%94%E7%A7%8D-IO-%E6%A8%A1%E5%9E%8B),下面介绍的主要是 Java 中 BIO、NIO、AIO 的区别。 ### 2.1 BIO 是阻塞的,NIO 是非阻塞的 1. BIO 的各种流是**阻塞的**,这就意味着,**当一个线程调用 `read()` 或 `write()` 时**,**该线程被阻塞**,**直到有一些数据被读取**,**或数据完全写入**,**在此期间**,**该线程不能再干其他任何事**,因此**在任何时候都可能有大量的线程处于休眠状态**,**只是等待输入或者输出就绪**,这**可以算为对资源的一种浪费**, 2. NIO 使我们可以进行**非阻塞**IO 操作,比如说,**单线程从通道读取数据到 Buffer**,同时**可以继续做别的事**,当**数据读取到 Buffer 中后**,线程**再进行处理数据**,写数据也是一样的,**一个线程请求写入一些数据到某通道**,但**不需要等待他完全写入**,这个线程**可以同时去做别的事情**,这样**可以提高线程的利用效率**。 ### 2.2 BIO 是面向流(Stream Oriented)的,NIO 是面向缓冲区(Buffer Oriented)的 1. Buffer 是**一个可以读写数据的内存块**,可以理解成一个**容器对象**(含数组),该对象**提供了一组方法**,**可以更轻松地使用内存块**,缓冲区对象**内置了一些机制**,**能够跟踪和记录缓冲区的状态变化**。 2. 在 NIO 类库中加入 Buffer 对象,体现了 NIO 与 BIO 的一个重要区别: 1. 在面向流的 BIO 中可以**将数据直接写入或者直接读到 Stream 对象中**,**每次从流中读取一个或者多个字节**,**直至读取完所有的字节**。 2. 在 NIO 库中,**所有数据都是用缓冲区处理的**,在**读取数据时**,他是**直接读缓冲区中的数据**,在**写入数据时**,也是**直接写到缓冲区中**,**任何时候访问 NIO 中的数据**,**都是通过缓冲区进行操作**,因此**在操作上更加灵活**,**读取速度也更加快**。 3. NIO 的 Buffer 除了做**缓冲块优化**之外,还**提供了一个可以直接访问物理内存的类 `DirectBuffer`**: 1. **普通的 Buffer 分配的是[JVM 堆内存](https://notebook.ricear.com/project-34/doc-541/#1-2-%E5%A0%86%E5%86%85%E5%AD%98)**,而`DirectBuffer`**是直接分配物理内存**。 2. **数据要输出到外部设备**,**必须先从用户空间复制到内核空间**,**再复制到输出设备**,而**则是直接将步骤简化为从内核空间复制到外部设备**,**减少了数据拷贝**。 3. 但是**由于 `DirectBuffer` 申请的是非 JVM 物理内存**,**所以创建和销毁的代价很高**,**不是直接由 JVM 负责垃圾回收**,而是**通过 Java 引用机制来释放该内存块**。 ### 2.3 NIO 通过 Channel 进行读写 1. 传统 IO 的流都是**单向**的,因此他们需要分为`Input Stream` 和`Output Stream`。 2. 而 NIO 中的 Channel 是**双向**的,**数据可以从 Channel 读到 Buffer 中**(使用`read()` 方法),**也可以从 Buffer 写到 Channel**(使用`write()` 方法)。 3. Channel 也**可以设置为非阻塞模式**,此时**当 Channel 从 Buffer 中读取数据时**,**如果有待读取的数据**,**则返回该数据**,**如果没有待读取的数据**,**对应的方法也不会被阻塞**,**而是直接返回**。![https://github.com/heibaiying](/media/202108/2021-08-23_1421330.6111752116340494.png) ### 2.4 NIO 有 Selector 实现多路复用,而 BIO 没有 1. Java NIO**实现了 IO 多路复用中的 Reactor 模型**: 1. **一个线程使用一个 Selector 通过轮询的方式去监听多个 Channel 上的事件**(`accept`、`read`),**如果某个 Channel 上面发生监听事件**,**这个 Channel 就处于就绪状态**,**然后进行 IO 操作**。 2. **可以将监听的 Channel 配置为非阻塞**,**这样当 Channel 上的 IO 事件还未到达时**,**就不会进入阻塞状态一直等待**,**而是继续轮询其他 Channel**,**找到 IO 事件已经到达的 Channel 执行**。 3. 因为创建和切换线程的开销很大,所以**使用一个线程来处理多个事件**,**减少了线程之间的切换**,**提高了系统的效率**。 > 需要注意的是: > > 1. **只有 `SocketChannel` 才能配置为非阻塞**,而`FileChannel`**不能**,因为`FileChannel`**配置非阻塞也没有意义**。 > 2. **目前操作系统的[IO 多路复用](https://notebook.ricear.com/project-26/doc-335)机制都是用了[epoll](https://notebook.ricear.com/project-26/doc-335/#3-3-2-3-epoll)**,**相比传统的 select 机制**,**epoll 没有最大连接句柄 1024 的限制**,所以**Selector 在理论上可以轮询成千上万的客户端**。 > ![https://github.com/heibaiying](/media/202108/2021-08-23_1425060.6312594694492627.png) ### 2.5 AIO 是真正意义上的异步 IO 1. AIO 是**一种异步非阻塞的通信模式**,**实现了真正意义上的异步 IO**,**直接将 IO 操作交给操作系统进行异步处理**。 ## 3 三种 IO 的适用场景 1. BIO 方式适用于**连接数目少且固定**的架构,**程序直观简单易理解**,是 JDK 1.4 以前的唯一选择。 2. NIO 方式适用于**连接数目多且连接比较短**(轻操作)的架构,比如聊天服务器,**编程比较复杂**,JDK 1.4 开始支持。 3. AIO 方式适用于**连接数目多且连接比较长**(重操作)的架构,比如相册服务器,**充分调用操作系统参与并发操作**,**编程比较复杂**,JDK 1.7 开始支持。 ## 参考文献 1. [offer 快到碗里来-Netty 核心面试题 15 连问](https://www.nowcoder.com/discuss/648088)。 2. [Java NIO](https://dunwu.github.io/javacore/io/java-nio.html)。 3. [Java BIO NIO AIO](https://weikeqin.com/2019/07/08/java-bio-nio-aio)。 4. [Java NIO 核心组件全解](https://juejin.cn/post/6855129006631550990)。
ricear
2021年8月23日 15:25
©
BY-NC-ND(4.0)
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码