news 2026/2/24 4:19:18

Java中的NIO详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java中的NIO详解

一、NIO简介

NIO中的N为NEW, IO为INPUT/OUTPUT,也就是民间所说的Non-Blocking IO,它拥有高并发能力,到JDK1.7 出现了NIO2.0。

在单线程的情况下,当前的IO操作即使没有完成,当前线程也能做其他事情,不用等待某个操作涉及的数据全部完成再进行其他操作。具体解释为:NIO的非阻塞模式下,线程发送数据与接收数据都是通过通道进行的,线程只需要去查看是否有数据要处理,如果没有就直接返回,不会等待。

二、NIO架构设计

Java NIO的核心组件包括:Channel(通道),Buffer(缓冲区),Selector(选择器)。

1、缓冲区(内存区域)

它本质上就是一个数组,提供了对数据的结构化访问以及维护读写位置等功能。

(1)缓冲区的作用:负责与通道进行交互。在面向流的IO中我们可以直接把数据写到Stream对象里,而面向通道的IO则不行,线程需要先把数据写入到缓冲区,再将缓冲区里的数据写到通道对象里。

(2)缓冲区的类别:最常用的是ByteBuffer(字节缓冲区),其他的还有CharBuffer、ShortBuffer等。ByteBuffer除了具有一般缓冲的操作之外还提供了一些特有操作,方便网络读写。

2、通道

通过它传输数据,与流的不同之处在于,通道是全双工的,同时支持读写操作,而流只能在一个方向上移动。

通道的作用:用于在字节缓冲区和通道的另一侧的实体(通常是一个文件或者套接字)进行有效的数据传输。

3、多路复用器(选择器)

它会不断地轮询注册在它上面的通道,并且返回那些准备就绪的通道,以便进行后续的IO处理。对应linux操作系统中的epoll。

注意:服务器客户端可分别有自己的多路复用器(选择器)。

三、ServerSocketChannel和SocketChannel的区别

它们是一对,位于java.nio中的通信的类。其中ServerSocketChannel是服务器端用的通道,SocketChannel是服务端/客户端均可用的通道。使用的时候必须先建立ServerSocketChannel通道来等待客户端的连接。客户端则必须建立相对应的SocketChannel(客户端会给该通道随机分配一个端口号)来与服务器建立连接,服务器接收到客户端的连接后,创建一个新的SocketChannel(该端口号与ServerSocketChannel端口号相同)并通过ServerSocketChannel.accept()方法与客户端的SocketChannel建立连接,之后双方就可以进行通信了。即服务器端的每一个SocketChannel都唯一标识了一个客户端。

现在我们给出一个测试样例,代码分为客户端和服务端,将它们分别放在不同的linux机器上,进行远程调用。注意客户端中申请连接用的IP和PORT一定是跟服务器中绑定的相同,否则无法建立连接。

注意:需要关系两台测试机器的防火墙;确定端口未被占用。

客户端代码如下:

java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.nio.charset.Charset; // NIO客户端 public class NIOClient { // 客户端的多路复用器(选择器) private Selector selector; // 与服务器通信的信道 SocketChannel socketChannel; static int sendCount = 0; public NIOClient(int port)throws IOException{ selector = Selector.open(); socketChannel = SocketChannel.open(); socketChannel.connect(new InetSocketAddress("9.30.249.84",port)); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); } private void startNIOClient() { // 启动客户端读线程:读取服务器端发来的信息 new Thread(new ClientReadThread()).start(); } class ClientReadThread implements Runnable { public void run() { try { while (selector.select() > 0) { // 遍历每个有可用IO操作Channel对应的SelectionKey for (SelectionKey sk : selector.selectedKeys()) { // 如果该SelectionKey对应的Channel中有可读的数据 if (sk.isReadable()) { // 使用NIO读取Channel中的数据 SocketChannel sc = (SocketChannel) sk.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); sc.read(readBuffer); readBuffer.flip(); // 将字节转化为为UTF-16的字符串
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/22 19:12:29

【完整源码+数据集+部署教程】食品分类2检测系统源码分享[一条龙教学YOLOV8标注好的数据集一键训练_70+全套改进创新点发刊_Web前端展示]

一、背景意义 随着全球人口的不断增长和生活水平的提高,食品安全与营养健康问题日益受到关注。食品种类繁多,消费者在选择食品时不仅关注其营养成分,还对食品的来源、品质和安全性提出了更高的要求。在此背景下,食品分类与检测技术…

作者头像 李华
网站建设 2026/2/14 0:23:03

【英飞凌 CY8CKIT-062S2-AI评测】-开发环境搭建与开发

过21IC网,申请到了英飞凌 CY8CKIT-062S2-AI开发板,该开发板是英飞凌的PSOC6系列的人工智能评估套件,它有一套创新工具用来原型制作和收集真实数据,以快速构建机器学习模型。硬件尺寸很小巧35mm*45mm,基于它可以建构边缘…

作者头像 李华
网站建设 2026/2/22 16:14:29

基于SpringBoot2+Vue2的企业合作与活动管理平台

企业合作与活动管理平台 演示视频 https://www.bilibili.com/video/BV1E4qpB9E8b/ 角色 管理员、普通用户、企业用户 技术 后端:Spring Boot 2、MySQL 前端:Vue.js 核心功能 本系统是一个企业合作与活动管理平台,旨在连接企业和普通用…

作者头像 李华
网站建设 2026/1/30 16:21:28

稀土抑烟剂在PVC材料中的防火与抑烟作用

PVC(聚氯乙烯)因耐用、易加工、成本低,被广泛应用于建筑管材、电线护套、地板和卷材等领域。但在火灾条件下,PVC燃烧容易产生大量烟雾和刺激性气体,不仅影响逃生,也增加了火灾危害。一、什么是稀土抑烟剂&a…

作者头像 李华
网站建设 2026/2/8 1:17:31

别让AI抢了你的饭碗:学会让它替你打工,才是未来的生存法则

朋友们,你有没有想过,未来的世界可能会被简单地分成两种人?一种是让AI替自己干活的人,另一种是活被AI抢走的人。这句话听起来有点残酷,但趋势已经摆在我们眼前。从写报告、做设计,到分析数据、客服应答&…

作者头像 李华
网站建设 2026/2/23 8:35:45

PinMe——极简、免费和无需服务器的开源前端部署工具

PinMe是一个开源的前端部署工具,它通过将静态网站文件上传到去中心化的IPFS网络来实现快速发布,主打极简、免费和无需服务器,目前Github 1.7k stars。 Github地址:https://github.com/glitternetwork/pinme PinMe 的官方网站&am…

作者头像 李华