2023年的金三银四招聘季并没有想象中的激烈。一个朋友在前段时间投了几十家公司,大都申请杳无音信。终于有了面试机会,却在被问到什么是NIO时答不上来。今日,咱们将深入了解Java NIO,以协助大家更好地理解这个概念。
什么是NIO?
Java NIO(Non-blocking Input/Output,非堵塞输入/输出)是Java供给的一种新的I/O处理结构,从Java 1.4开端引入。NIO旨在进步I/O操作的功能和可扩展性。它答应单线程中处理多个I/O操作,然后避免了传统I/O(称为堵塞I/O或BIO)中每个衔接需要一个线程的问题。
NIO架构图
NIO的首要特点包含:
- 非堵塞I/O:NIO支撑非堵塞I/O操作,这意味着线程能够在等候I/O操作完结的一同履行其他使命。这有助于进步线程的利用率和体系的功能。
- 通道(Channel) :通道是衔接数据源和方针的首要组件。它答应数据在数据源和方针之间高效地传输。通道可所以文件、套接字等。Channel类似于传统I/O中的流,但它们支撑非堵塞操作。
- 缓冲区(Buffer) :缓冲区是NIO中用于暂时存储数据的容器。它供给了对数据的结构化访问,一同还支撑数据的批量操作。在NIO中,一切数据的输入和输出都通过缓冲区进行。
- 多路复用器(Selector) :多路复用器是NIO中的一个关键组件,它答应单个线程监听多个通道的I/O事情。当某个通道准备好进行I/O操作时,多路复用器会告诉相关线程。这使得一个线程能够处理多个并发衔接,然后进步了体系的可扩展性
Channel详解
通道的首要作用是进行数据传输,一般涉及到读取和写入操作。Channel与传统的I/O流有必定相似性,但它们之间也存在一些差异。
- Channel的双向性:与传统的I/O流不同,Channel一般是双向的,这意味着一个Channel既能够用于读取数据,也能够用于写入数据。然而,也有一些特定类型的Channel只支撑单向操作,例如只读或只写。
- 非堵塞操作:Channel支撑非堵塞操作,这是它与传统I/O流的一个明显差异。在非堵塞形式下,Channel不会在履行读取或写入操作时堵塞当时线程。这样能够进步程序的响应速度和功能。
在Java NIO中,通道有以下几种类型:
- FileChannel:用于文件操作的通道。它支撑从文件中读取数据和向文件中写入数据。注意,FileChannel不支撑非堵塞操作。
- SocketChannel:用于套接字衔接的通道。它支撑TCP衔接,而且能够在非堵塞形式下作业。这使得它十分合适完成多路复用的网络通信。
- ServerSocketChannel:用于服务器套接字的通道。它首要用于监听传入的TCP衔接,并在有新衔接抵达时创立与之对应的SocketChannel。
- DatagramChannel:用于UDP数据传输的通道。它支撑非堵塞操作,能够完成高效的数据报文传输。
- Channel一般与缓冲区(Buffer)一同运用。缓冲区是一块连续的内存区域,用于存储数据。当数据从Channel读取到缓冲区时,应用程序能够对这些数据进行处理;当数据从缓冲区写入到Channel时,数据会被传输到方针。
缓冲区(Buffer)详解
缓冲区具有以下特点:
- 容量(Capacity):缓冲区的容量表明缓冲区内能够存储的元素数量。容量在缓冲区创立时被指定,而且在缓冲区的整个生命周期中不会产生改动。
- 约束(Limit):缓冲区的约束表明第一个不应该读取或写入的元素方位。换句话说,缓冲区内部的有用数据范围是从第一个元素开端到约束方位之前的一切元素。
- 方位(Position):缓冲区的方位表明下一个要读取或写入的元素的索引。当读取或写入数据时,方位会跟着操作的进行而改动。
- 符号(Mark):缓冲区的符号是一个可选的属性,用于记忆特定的方位。通过调用mark()办法,能够将当时方位作为符号。在将来,能够运用reset()办法将方位重置回从前符号的当地。
在Java NIO中,缓冲区有多种类型,它们对应于基本数据类型。例如:
- ByteBuffer:存储字节数据的缓冲区。
- CharBuffer:存储字符数据的缓冲区。
- ShortBuffer:存储短整型数据的缓冲区。
- IntBuffer:存储整型数据的缓冲区。
- LongBuffer:存储长整型数据的缓冲区。
- FloatBuffer:存储浮点数数据的缓冲区。
- DoubleBuffer:存储双精度浮点数数据的缓冲区。
缓冲区的首要操作有:
- 读取(Read):从缓冲区中获取数据。
- 写入(Write):将数据写入缓冲区。
- 翻转(Flip):将缓冲区的状况从写入形式切换到读取形式,一同将方位重置为0,并将约束设置为当时方位。
- 清空(Clear):清空缓冲区内的数据,将方位重置为0,约束设置为容量。
- 压缩(Compact):将未读取的数据移到缓冲区的开头,并将方位设置为未读取数据的结尾,约束设置为容量。
缓冲区的中心作用是在数据源和方针之间暂时存储数据,以便Channel进行读取和写入操作
多路复用器(Selector)
多路复用器(Selector)在Java NIO中起到了关键作用,它能够让单个线程一同管理多个通道,处理各种I/O事情。多路复用器的中心概念是通过在一个线程上轮询通道的事情状况,使得程序能够高效地处理多个通道上的I/O操作。这种设计形式也被称为Reactor形式。
Selector首要担任以下几个方面的功能:
- 注册通道:将通道注册到Selector上,使得Selector能够监听这些通道的I/O事情。
- 监听事情:Selector会不断轮询一切注册的通道,检测它们的事情状况(例如:是否可读、可写等)。
- 告诉:当某个通道准备好进行某种I/O操作时,Selector会告诉相应的线程。线程随后能够对该通道进行适当的操作,例如:读取、写入等。
- 撤销注册:当一个通道不再需要被监听时,能够从Selector上撤销注册。
通过运用多路复用器(Selector),咱们能够运用较少的线程来处理很多的并发衔接,然后进步体系的功能和可扩展性。这对于构建高功能的网络服务和应用程序十分有协助。