java当中什么是NIO

news/2024/9/17 7:10:00/ 标签: java, nio, 开发语言

Java中的NIO(Non-blocking I/O)即非阻塞I/O,是Java 1.4中引入的一种新的I/O API,用于替代传统的I/O(即BIO, Blocking I/O)。与传统的阻塞式I/O相比,NIO提供了更高效的I/O操作,特别是在处理大量并发连接时表现更好。NIO通过使用通道(Channel)和缓冲区(Buffer)来实现对I/O操作的非阻塞处理。本文将从NIO的基本概念、核心组件、常见用法、与BIO的对比及其优缺点等多个方面详细介绍Java中的NIO。

一、NIO的基本概念

NIO全称为Non-blocking I/O,直译为非阻塞I/O。传统的I/O操作通常是阻塞的,即在进行I/O操作时,程序会被阻塞,直到操作完成。而NIO允许程序在不阻塞的情况下执行I/O操作,即程序可以在等待I/O操作完成的同时执行其他任务,从而提升系统的并发能力和资源利用率。

NIO主要引入了以下三个核心概念:

  1. 通道(Channel):通道可以看作是一个连接源和目标的通道,数据可以通过通道从一个地方传输到另一个地方。通道类似于传统的流(Stream),但与流不同的是,通道是双向的,可以用于读、写或同时进行读写操作。

  2. 缓冲区(Buffer):缓冲区是一个用于存储数据的容器,所有数据都是通过缓冲区进行处理的。缓冲区本质上是一个数组,但它提供了对数据的结构化访问以及维护读写位置的功能。

  3. 选择器(Selector):选择器是NIO中的一个重要组件,它可以用于监听多个通道的事件(如连接请求、数据到达等)。通过选择器,程序可以在一个线程中处理多个通道,从而大大提高了I/O处理的效率。

二、NIO的核心组件

Java NIO由以下几个核心组件构成,这些组件共同提供了高效的I/O操作能力:

  1. 通道(Channel)
       - FileChannel:用于文件数据的读写操作。
       - SocketChannel:用于网络数据的TCP连接。
       - ServerSocketChannel:用于监听新的TCP连接,就像传统的ServerSocket一样。
       - DatagramChannel:用于UDP连接的读写操作。

  2. 缓冲区(Buffer)
       - ByteBuffer:用于存储字节数据。
       - CharBufferIntBufferLongBufferFloatBufferDoubleBuffer等:分别用于存储不同类型的基本数据类型。

  3. 选择器(Selector)
       - 选择器用于监控多个通道的事件,支持非阻塞I/O操作。通过调用选择器的select()方法,可以知道有哪些通道准备好了I/O操作。

三、NIO的常见用法

1. 文件I/O操作

NIO提供了FileChannel用于文件的读写操作。与传统的FileInputStreamFileOutputStream不同,FileChannel可以通过ByteBuffer进行非阻塞读写操作。

java">RandomAccessFile file = new RandomAccessFile("data.txt", "rw");
FileChannel channel = file.getChannel();ByteBuffer buffer = ByteBuffer.allocate(48);
int bytesRead = channel.read(buffer);while (bytesRead != -1) {buffer.flip(); // 切换为读模式while (buffer.hasRemaining()) {System.out.print((char) buffer.get());}buffer.clear(); // 清空缓冲区,为下次写入数据做好准备bytesRead = channel.read(buffer);
}file.close();
2. 网络I/O操作

NIO的SocketChannelServerSocketChannel提供了对网络连接的非阻塞处理。下面是一个简单的基于NIO的Echo服务器的示例:

java">ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false); // 设置为非阻塞模式Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectedKeys.iterator();while (iterator.hasNext()) {SelectionKey key = iterator.next();if (key.isAcceptable()) {// 接受新的连接SocketChannel clientChannel = serverSocketChannel.accept();clientChannel.configureBlocking(false);clientChannel.register(selector, SelectionKey.OP_READ);} else if (key.isReadable()) {// 读取数据SocketChannel clientChannel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(256);clientChannel.read(buffer);buffer.flip();clientChannel.write(buffer);buffer.clear();}iterator.remove(); // 移除已处理的键}
}

四、NIO与BIO的对比

  1. 阻塞与非阻塞
       - BIO:采用阻塞I/O模式,线程在进行I/O操作时会被阻塞,无法处理其他任务。
       - NIO:采用非阻塞I/O模式,线程可以在I/O操作未完成时继续处理其他任务,提高了系统的并发能力。

  2. I/O多路复用
       - BIO:通常需要为每个客户端连接创建一个独立的线程,这在大量并发连接的情况下会带来巨大的线程开销。
       - NIO:通过选择器(Selector)实现I/O多路复用,能够在一个线程中处理多个通道,减少了线程的开销。

  3. 性能
       - BIO:适用于连接数较少且处理时间较长的场景,如传统的单线程服务器。
       - NIO:适用于连接数较多且连接较短的场景,如高并发的聊天服务器、游戏服务器等。

五、NIO的优缺点

优点:
  1. 高效处理并发连接:NIO通过非阻塞I/O和选择器机制能够在单线程中处理大量并发连接,适合高并发场景。
  2. I/O多路复用:NIO允许多个通道共用一个线程进行管理,减少了线程的资源消耗。
  3. 灵活性:NIO的通道、缓冲区、选择器提供了比传统I/O更为灵活的数据处理方式。
缺点:
  1. 编程复杂度高:与BIO相比,NIO的编程模型更复杂,开发者需要管理选择器、通道、缓冲区等多个组件,这增加了代码的复杂性。
  2. 适用场景有限:NIO的优势在于高并发场景,但对于低并发、长连接的场景,BIO可能会更简单高效。

六、NIO的应用场景

NIO广泛应用于需要高并发处理的场景,以下是一些常见的应用场景:

  1. 高并发网络服务器:如HTTP服务器、聊天服务器、游戏服务器等,通过NIO可以在一个或少量线程中处理大量并发请求。
  2. 文件处理:NIO的FileChannel提供了对文件的高效读写操作,特别是对于大文件的处理,NIO能够显著提升性能。
  3. 事件驱动架构:NIO中的选择器机制非常适合用于事件驱动的应用,如GUI框架、事件处理系统等。

结语

Java NIO作为一种高效的I/O处理方式,特别适合于需要处理大量并发连接的场景。通过使用通道、缓冲区和选择器,NIO在提供非阻塞I/O操作的同时,也提供了灵活的数据处理能力。尽管NIO的编程模型比传统的BIO更为复杂,但在高并发、高性能的应用中,NIO无疑是一个值得选择的解决方案。随着Java的发展,NIO已经成为Java生态中不可或缺的重要组成部分,未来它在高性能计算和并发处理领域将继续发挥重要作用。


http://www.ppmy.cn/news/1522446.html

相关文章

深度学习速通系列:如何计算文本相似度

计算文本相似度是自然语言处理&#xff08;NLP&#xff09;中的一个常见任务&#xff0c;用于衡量两个文本片段在语义上的相似性或相关性。以下是一些常用的方法&#xff1a; 余弦相似度&#xff1a; 将文本转换为向量&#xff08;例如&#xff0c;使用词袋模型或TF-IDF&#x…

SpringBoot开启多端口探究--基于多ApplicationContext

文章目录 前情提要一、思路概要二、具体实现三、其他问题父子关系部分依赖 总结 前情提要 前面探讨了management端口开启&#xff0c;grpc端口开启&#xff0c;本文继续探讨在SpringApplication中开启多个端口的方式之多ApplicationContext, 相比management端口基于多WebServe…

内卷时代无人机培训机构如何做大做强

在当今社会&#xff0c;随着科技的飞速发展&#xff0c;“内卷”一词频繁被提及&#xff0c;反映了各行业竞争日益激烈的现象。对于无人机培训行业而言&#xff0c;如何在这样的时代背景下脱颖而出&#xff0c;实现做大做强的目标&#xff0c;成为每个培训机构必须深思的问题。…

unity 实现吸血鬼幸存者的随机奖励

设置奖励的数据类型 // // Auto Generated Code By excel2json // https://neil3d.gitee.io/coding/excel2json.html // 1. 每个 Sheet 形成一个 Struct 定义, Sheet 的名称作为 Struct 的名称 // 2. 表格约定&#xff1a;第一行是变量名称&#xff0c;第二行是变量类型// Gen…

【Webpack】基本使用方法

&#x1f4e2;博客主页&#xff1a;逆旅行天涯-CSDN博客 &#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 参考视频&#xff1a; 30 分钟掌握 Webpack_哔哩哔哩_bilibili 什么是webpack 简单来说就是一个 打包工具&#xff0c; 可…

在Ubuntu 18.04上安装Nginx的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 介绍 Nginx 是世界上最流行的 Web 服务器之一&#xff0c;负责托管互联网上一些最大和最高流量的网站。在大多数情况下&#xff0c;它比…

OpenHarmony鸿蒙开发( Beta5.0)智能手表应用开发实践

样例简介 本项目是基于BearPi套件开发的智能儿童手表系统&#xff0c;该系统通过与GSM模块&#xff08;型号&#xff1a;SIM808&#xff09;的通信来实现通话和定位功能。 智能儿童手表系统可以通过云和手机建立连接&#xff0c;同步时间和获取天气信息&#xff0c;通过手机下…

Redis缓存预热方案详解:提升应用性能与用户体验

文章目录 引言1. 为什么需要缓存预热&#xff1f;2. 缓存预热的基本原理2.1 数据选择2.2 加载策略 3. Redis缓存预热方案设计3.1 方案概述3.2 数据选择3.3 加载策略3.4 实现方式 4. 测试与监控4.1 单元测试4.2 监控 5. 总结 引言 在现代Web应用中&#xff0c;缓存技术已经成为…

云原生之WEB应用服务器Tomcat(持续更新中)

WEB应用服务器Tomcat 1.Tomcat功能介绍1.1 安装Tomcat1.2 生成启动文件 2.结合反向代理实现Tomcat部署2.1 利用nginx反向代理实现 3.Memcached&#xff08;解决sion丢失问题&#xff09;3.1 简介3.2 安装与启动 4.session 共享服务器 1.Tomcat功能介绍 Tomcat 服务器是一个免费…

论文精读-Supervised Raw Video Denoising with a Benchmark Dataset on Dynamic Scenes

论文精读-Supervised Raw Video Denoising with a Benchmark Dataset on Dynamic Scenes 优势 1、构建了一个用于监督原始视频去噪的基准数据集。为了多次捕捉瞬间&#xff0c;我们手动为对象s创建运动。在高ISO模式下捕获每一时刻的噪声帧&#xff0c;并通过对多个噪声帧进行…

[数据集][目标检测]井盖丢失未盖破损检测数据集VOC+YOLO格式2890张5类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;2890 标注数量(xml文件个数)&#xff1a;2890 标注数量(txt文件个数)&#xff1a;2890 标注…

使用Nginx获取客户端真实IP(real_ip_header)

使用 Nginx 获取客户端真实 IP 在使用 Nginx 作为反向代理或负载均衡器时&#xff0c;我们常常需要获取客户端的真实 IP 地址。然而&#xff0c;默认情况下&#xff0c;Nginx 的 $remote_addr 变量记录的 IP 地址可能是上游代理或负载均衡器的 IP&#xff0c;而非实际客户端的…

MySQL · 性能优化 · 提高查询效率的实用指南(上)

前言 在过去的几年里&#xff0c;MySQL作为一款开源数据库&#xff0c;因其稳定性和性能得到了广泛的应用。始终保持着强劲的增长趋势&#xff0c;越来越多的企业和开发者将其作为首选数据库&#xff0c;甚至有部分企业从Oracle迁移至MySQL。然而&#xff0c;随着使用的普及&a…

Django中的第一个自动化测试编写

跟着Django官网中的投票应用学习&#xff0c;其中有官方说明的一个bug:如果 Question 是在一天之内发布的&#xff0c;那么这个Question 应该显示“published_recently”&#xff0c;返回值为True &#xff0c;然而现在如果问题发布时间为30天之后(未来时间)&#xff0c;也会返…

防封!数字人直播防封!铭顺科技AI数智人抖音直播防封落地方案!!

数字人直播防不防封&#xff1f; 数字人直播有没有流量&#xff1f; 数字人直播能不能落地&#xff1f; 这是目前所有想入局AI数字人赛道、想用数字人直播、想做数字人项目的老板们最担心、最关心的问题&#xff01;但是&#xff0c;同行友商对此都噤若寒蝉&#xff0c;不敢跟…

手机同时传输USB功能与充电的实现及LDR6500的作用

在智能设备日益普及的今天&#xff0c;用户对于手机的功能需求愈发多样化&#xff0c;其中同时实现USB数据传输与充电功能成为了许多用户的迫切需求。这一功能的实现离不开先进的硬件技术和创新的芯片解决方案&#xff0c;而LDR6500正是这样一款能够满足这一需求的USB PD&#…

Spark与Kafka进行连接

在Java中使用Spark与Kafka进行连接&#xff0c;你可以使用Spark Streaming来处理实时流数据。以下是一个简单的示例&#xff0c;展示了如何使用Spark Streaming从Kafka读取数据并进行处理。 1. 引入依赖 首先&#xff0c;在你的pom.xml文件中添加必要的依赖项&#xff08;假设…

nginx配置负载均衡的几种方式

1&#xff0c;轮询&#xff08;默认&#xff09; 每个请求按时间顺序逐一分配到不同的后端服务器&#xff0c;如果后端服务器 down掉&#xff0c;能自动剔除。 # 反向代理配置upstream server_list{# 这个是tomcat的访问路径server localhost:8080;server localhost:9999;}serv…

八股集合1

在HTTPS中&#xff0c;加密方法主要包括两种类型的加密技术&#xff1a;非对称加密&#xff08;也称为公钥加密&#xff09;和对称加密。这两种加密技术在HTTPS握手过程中协同工作&#xff0c;确保数据的安全传输。下面是具体的加密方法及其作用&#xff1a; 公钥加密 (非对称…

无人机飞控之光流知识小结

要完成飞行器的定位&#xff0c;则必须要有位置的反馈数据。在户外&#xff0c;我们一般使用GPS作为位置传感器&#xff0c;然而&#xff0c;在室内&#xff0c;GPS无法使用&#xff0c;要完成定位功能&#xff0c;可以选用光流传感器。 本讲主要介绍如何通过下视摄像头估计飞…