Java NIO学习(一):Java NIO概述

简介: IO 的操作方式通常分为几种:同步阻塞 BIO、同步非阻塞 NIO、异步非阻塞 AIO。

一、 IO 概述



IO 的操作方式通常分为几种:同步阻塞 BIO、同步非阻塞 NIO、异步非阻塞 AIO。


(1)在 JDK1.4 之前,我们建立网络连接的时候采用的是 BIO 模式。


(2)Java NIO(New IO 或 Non Blocking IO)是从 Java 1.4 版本开始引入的一个新的IO API,可以替代标准的 Java IO API。NIO 支持面向缓冲区的、基于通道的 IO 操作。NIO 将以更加高效的方式进行文件的读写操作。BIO 与 NIO 一个比较重要的不同是,我们使用 BIO 的时候往往会引入多线程,每个连接对应一个单独的线程;而 NIO 则是使用单线程或者只使用少量的多线程,让连接共用一个线程。


(3)AIO 也就是 NIO 2,在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO 模型。


下面我们来详细介绍这几种 IO 方式


二、阻塞 IO (Blocking IO)



阻塞 IO(BIO)是最传统的一种 IO 模型,即在读写数据过程中会发生阻塞现象,直至有可供读取的数据或者数据能够写入。


(1)在 BIO 模式中,服务器会为每个客户端请求建立一个线程,由该线程单独负责处理一个客户请求,这种模式虽然简单方便,但由于服务器为每个客户端的连接都采用一个线程去处理,使得资源占用非常大。因此,当连接数量达到上限时,如果再有用户请求连接,直接会导致资源瓶颈,严重的可能会直接导致服务器崩溃。


(2)大多数情况下为了避免上述问题,都采用了线程池模型。也就是创建一个固定大小的线程池,如果有客户端请求,就从线程池中取一个空闲线程来处理,当客户端处理完操作之后,就会释放对线程的占用。因此这样就避免为每一个客户端都要创建线程带来的资源浪费,使得线程可以重用。但线程池也有它的弊端,如果连接大多是长连接,可能会导致在一段时间内,线程池中的线程都被占用,那么当再有客户端请求连接时,由于没有空闲线程来处理,就会导致客户端连接失败。传统的 BIO 模式如下图所示:

247d3b9fe234f0b6f2cca11777411f4f.png


三、非阻塞 IO(Non Blocking IO)



基于 BIO 的各种弊端,在JDK1.4 开始出现了高性能 IO 设计模式非阻塞 IO(NIO)。


(1)NIO采用非阻塞模式,基于 Reactor 模式的工作方式,I/O 调用不会被阻塞,它的实现过程是:会先对每个客户端注册感兴趣的事件,然后有一个线程专门去轮询每个客户端是否有事件发生,当有事件发生时,便顺序处理每个事件,当所有事件处理完之后,便再转去继续轮询。如下图所示:

1eaf7695aae5af6479f16e490d3a7d58.png


(2)NIO 中实现非阻塞 I/O 的核心对象就是 Selector,Selector 就是注册各种 I/O 事件地方,而且当我们感兴趣的事件发生时,就是这个对象告诉我们所发生的事件,如下图所示:


c8e0b94cabb2da7a787e8ceec775df8e.png

(3)NIO 的最重要的地方是当一个连接创建后,不需要对应一个线程,这个连接会被注册到多路复用器上面,一个选择器线程可以同时处理成千上万个连接,系统不必创建大量的线程,也不必维护这些线程,从而大大减小了系统的开销。


O

NIO

面向流(Stream Oriented)

面向缓冲区(Buffer Oriented)

阻塞IO(Blocking IO)

非阻塞IO(Non Blocking IO)

选择器(Selectors)


四、异步非阻塞 IO(AIO)



AIO 也就是 NIO 2,在 Java 7 中引入了NIO 的改进版 NIO 2,它是异步非阻塞的 IO 模型。异步 IO 是基于事件和回调机制实现的,也就是说 AIO 模式不需要 selector 操作,而是是事件驱动形式,也就是当客户端发送数据之后,会主动通知服务器,接着服务器再进行读写操作。


Java 的 AIO API 其实就是Proactor 模式的应用,和 Reactor 模式类似。Reactor 和 Proactor 模式的主要区别就是真正的读取和写入操作是有谁来完成的,Reactor 中需要应用程序自己读取或者写入数据,而 Proactor 模式中,应用程序不需要进行实际的读写过程,它只需要从缓存区读取或者写入即可,操作系统会读取缓存区或者写入缓存区到真正的 IO 设备。


五、NIO概述



Java NIO 由以下几个核心部分组成:


  • Channels
  • Buffers
  • Selectors


虽然 Java NIO 中除此之外还有很多类和组件,但 Channel,Buffer 和Selector 构成了核心的 API。其它组件,如 Pipe和 FileLock,只不过是与三个核心组件共同使用的工具类。


5.1 Channel


首先说一下 Channel,可以翻译成“通道”。Channel 和 IO 中的Stream(流)是差不多一个等级的。只不过 Stream 是单向的,譬如:InputStream, OutputStream;而Channel 是双向的,既可以用来进行读操作,又可以用来进行写操作。NIO 中的 Channel 的主要实现有:FileChannel、DatagramChannel、SocketChannel 和 ServerSocketChannel,这里看名字就可以猜出:分别可以对应文件 IO、UDP 和 TCP(Server 和 Client)。


5.2 Buffer


NIO 中的关键 Buffer 实现有:ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer,LongBuffer, ShortBuffer,分别对应基本数据类型: byte, char, double,float, int, long, short。


5.3 Selector


Selector 运行单线程处理多个 Channel,如果你的应用打开了多个通道,但每个连接的流量都很低,使用Selector 就会很方便。例如在一个聊天服务器中。要使用Selector, 得向 Selector 注册 Channel,然后调用它的 select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新的连接进来、数据接收等。


1.5.4 Channel Buffer Selector 三者关系


一个 Channel 就像一个流,只是 Channel 是双向的,Channel 读数据到 Buffer, Buffer 写数据到Channel。


d2e2ea745b0340a461c757f64e77b5bd.png

一个 selector 允许一个线程处理多个 channel。

5f72149be78af7cf019826f61c8ce76f.png


目录
打赏
0
0
0
0
178
分享
相关文章
课时2:Java简介(Java发展概述)
课时2:Java简介(Java发展概述) 摘要: 1. Java基础知识:介绍Java作为编程语言及其思想。 2. Java的发展历史:从1991年GREEN项目到1995年正式推出,历经网景公司、HotJava浏览器等关键节点。 3. Java的版本信息:涵盖从JDK 1.0到JDK 1.8的主要版本及特性,如Lambda表达式和模块化支持。
Java线程池ExecutorService学习和使用
通过学习和使用Java中的 `ExecutorService`,可以显著提升并发编程的效率和代码的可维护性。合理配置线程池参数,结合实际应用场景,可以实现高效、可靠的并发处理。希望本文提供的示例和思路能够帮助开发者深入理解并应用 `ExecutorService`,实现更高效的并发程序。
65 10
JAVA网络IO之NIO/BIO
本文介绍了Java网络编程的基础与历史演进,重点阐述了IO和Socket的概念。Java的IO分为设备和接口两部分,通过流、字节、字符等方式实现与外部的交互。
【潜意识Java】深度分析黑马项目《苍穹外卖》在Java学习中的重要性
《苍穹外卖》项目对Java学习至关重要。它涵盖了用户管理、商品查询、订单处理等模块,涉及Spring Boot、MyBatis、Redis等技术栈。
336 4
【潜意识Java】Java基础教程:从零开始的学习之旅
本文介绍了 Java 编程语言的基础知识,涵盖从简介、程序结构到面向对象编程的核心概念。首先,Java 是一种高级、跨平台的面向对象语言,支持“一次编写,到处运行”。接着,文章详细讲解了 Java 程序的基本结构,包括包声明、导入语句、类声明和 main 方法。随后,深入探讨了基础语法,如数据类型、变量、控制结构、方法和数组。此外,还介绍了面向对象编程的关键概念,例如类与对象、继承和多态。最后,针对常见的编程错误提供了调试技巧,并总结了学习 Java 的重要性和方法。适合初学者逐步掌握 Java 编程。
72 1
|
6月前
|
Java学习十六—掌握注解:让编程更简单
Java 注解(Annotation)是一种特殊的语法结构,可以在代码中嵌入元数据。它们不直接影响代码的运行,但可以通过工具和框架提供额外的信息,帮助在编译、部署或运行时进行处理。
144 43
Java学习十六—掌握注解:让编程更简单
|
4月前
|
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
111 3
|
4月前
|
Java的NIO体系
通过本文的介绍,希望您能够深入理解Java NIO体系的核心组件、工作原理及其在高性能应用中的实际应用,并能够在实际开发中灵活运用这些知识,构建高效的Java应用程序。
110 5

热门文章

最新文章