Java中的五种I/O模型详解

一、阻塞I/O(Blocking I/O)

1.1 概念

阻塞I/O是最传统的I/O模型。在该模型中,当一个线程执行I/O操作时,如果没有数据可读或可写,线程将会被阻塞,直到I/O操作完成。

1.2 工作原理

  • 当线程调用读取或写入数据的方法时,如果操作无法立即完成,线程将进入阻塞状态。
  • 阻塞状态持续到操作完成或发生错误。

1.3 示例代码

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class BlockingIOExample {public static void main(String[] args) {try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {String line;while ((line = reader.readLine()) != null) {System.out.println(line);}} catch (IOException e) {e.printStackTrace();}}
}

1.4 优缺点

  • 优点

    • 实现简单,易于理解和使用。
  • 缺点

    • 线程阻塞会浪费系统资源,尤其在高并发场景下,效率较低。

1.5 适用场景

适合于I/O操作较少或对性能要求不高的场景,如简单的文件读写操作。

二、非阻塞I/O(Non-blocking I/O)

2.1 概念

非阻塞I/O模型允许线程在执行I/O操作时不被阻塞。当I/O操作无法立即完成时,线程可以继续执行其他任务。

2.2 工作原理

  • 使用非阻塞模式打开I/O通道。
  • 当调用读取或写入方法时,方法立即返回,指示操作是否成功。
  • 线程可以在之后的某个时间再尝试I/O操作。

2.3 示例代码

import java.io.IOException;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;public class NonBlockingIOExample {public static void main(String[] args) {try {Selector selector = Selector.open();ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.configureBlocking(false);serverChannel.socket().bind(new java.net.InetSocketAddress(8080));serverChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();for (SelectionKey key : selector.selectedKeys()) {// 处理I/O操作}}} catch (IOException e) {e.printStackTrace();}}
}

2.4 优缺点

  • 优点

    • 提高了程序的灵活性,允许线程同时处理多个I/O操作。
  • 缺点

    • 编码复杂度增加,管理状态和错误处理较为麻烦。

2.5 适用场景

适用于高并发场景,如网络服务器,能够有效提高资源利用率。

三、选择器I/O(Selector I/O)

3.1 概念

选择器I/O是Java NIO中的一部分,通过选择器(Selector)来管理多个通道的I/O操作。选择器可以同时监控多个通道的状态,线程可以根据需要进行处理。

3.2 工作原理

  • 使用选择器注册多个通道。
  • 选择器可以监听通道的可读、可写等事件。
  • 当某个通道的状态发生变化时,选择器会通知相关线程。

3.3 示例代码

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;public class SelectorIOExample {public static void main(String[] args) {try {Selector selector = Selector.open();ServerSocketChannel serverChannel = ServerSocketChannel.open();serverChannel.bind(new InetSocketAddress(8080));serverChannel.configureBlocking(false);serverChannel.register(selector, SelectionKey.OP_ACCEPT);while (true) {selector.select();for (var key : selector.selectedKeys()) {if (key.isAcceptable()) {SocketChannel clientChannel = serverChannel.accept();clientChannel.configureBlocking(false);clientChannel.register(selector, SelectionKey.OP_READ);}if (key.isReadable()) {// 读取数据}}}} catch (IOException e) {e.printStackTrace();}}
}

3.4 优缺点

  • 优点

    • 可以有效管理多个I/O通道,提高并发处理能力。
  • 缺点

    • 实现较复杂,需要对选择器和通道有深入了解。

3.5 适用场景

适用于需要处理大量连接的网络服务器,特别是当连接数远超线程数时。

四、NIO(New I/O)

4.1 概念

Java NIO是Java 1.4引入的一个新的I/O库,提供了更为高效的I/O处理能力。NIO支持缓冲区、通道、选择器等概念,支持非阻塞I/O操作。

4.2 工作原理

  • 缓冲区:数据在传输过程中先被存放在缓冲区中,提高了数据读写的效率。
  • 通道:通过通道进行数据传输,支持非阻塞操作。
  • 选择器:用于管理多个通道,提高I/O处理能力。

4.3 示例代码

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.FileChannel;
import java.nio.file.StandardOpenOption;public class NIOExample {public static void main(String[] args) {try (FileChannel fileChannel = FileChannel.open(java.nio.file.Paths.get("example.txt"), StandardOpenOption.READ)) {ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = fileChannel.read(buffer);while (bytesRead != -1) {System.out.println("Read " + bytesRead + " bytes.");buffer.clear();bytesRead = fileChannel.read(buffer);}} catch (IOException e) {e.printStackTrace();}}
}

4.4 优缺点

  • 优点

    • 提高了I/O性能,特别是在高并发场景下。
    • 支持文件、网络、数据流等多种I/O操作。
  • 缺点

    • 学习曲线较陡,API相对复杂。

4.5 适用场景

适用于高性能和高并发的应用,如网络服务器、文件服务器等。

五、异步I/O(Asynchronous I/O)

5.1 概念

异步I/O是指在进行I/O操作时,程序不需要等待操作完成,而是可以继续执行其他任务。Java通过java.nio.channels.AsynchronousChannel类提供了异步I/O支持。

5.2 工作原理

  • 异步I/O操作通过回调机制来处理结果。
  • 当I/O操作完成后,系统会自动调用注册的回调函数。

5.3 示例代码

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;public class AsyncIOExample {public static void main(String[] args) {try (AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(Paths.get("example.txt"), StandardOpenOption.READ)) {ByteBuffer buffer = ByteBuffer.allocate(1024);fileChannel.read(buffer, 0, null, new java.nio.channels.CompletionHandler<Integer, Void>() {@Overridepublic void completed(Integer result, Void attachment) {System.out.println("Read " + result + " bytes.");}@Overridepublic void failed(Throwable exc, Void attachment) {exc.printStackTrace();}});} catch (IOException e) {e.printStackTrace();}}
}

5.4 优缺点

  • 优点

    • 充分利用系统资源,避免线程阻塞。
    • 提高程序的响应性。
  • 缺点

    • 回调机制可能导致代码复杂性增加。
    • 调试难度相对较高。

5.5 适用场景

适用于高并发、需要快速响应的应用,如实时数据处理和大规模网络应用。

六、总结

Java提供了多种I/O模型,各具优缺点和适用场景。阻塞I/O适合简单场景,非阻塞I/O和选择器I/O适用于高并发的网络应用,NIO和异步I/O则能提供更高的性能和响应性。在实际开发中,选择合适的I/O模型对于提高程序性能至关重要。

希望本文能帮助你深入理解Java中的五种I/O模型,提升你的编程能力。如有任何问题或讨论,欢迎随时交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/55242.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决nginx+tomcat宕机完美解决方案

问题描述&#xff1a;公司项目太老了&#xff0c;还是tomcat项目&#xff0c;部署两台tomcat,做了nginx负载。最近发现每到上午10&#xff0c;下午3点&#xff0c;tomcat就宕机了&#xff0c;死活找不到原因&#xff0c;客户影响超期差&#xff0c;实在让人头疼。 解决思路&am…

今日指数项目实现个股日K线详情功能

个股日K线详情功能 一. 什么是个股日K线 1.日K线就是将股票交易流水按天分组&#xff0c;然后统计出每天的交易数据&#xff0c;内容包含&#xff1a;日期、股票编码、名称、最高价、最低价、开盘价、收盘价、前收盘价、交易量&#xff1b; 2.需要注意的是这里的收盘价就是指…

MySQL:进阶巩固-存储过程

目录 一、存储过程的概述二、存储过程的基本使用2.1 创建存储过程2.2 使用存储过程2.3 查询指定数据库的存储过程以及状态信息2.4 查看某个存储过程的定义2.5 删除存储过程2.6 案例 三、存储过程的变量设置3.1 系统变量3.2 用户自定义变量3.3 局部变量 四、IF判断五、参数六、C…

spring boot项目对接人大金仓

先确认一下依赖 第一 是否引入了mybatis-plus多数据源&#xff0c;如果引入了请将版本保持在3.5.0以上 <dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>${dynam…

LeetCode 热题 100 回顾18

干货分享&#xff0c;感谢您的阅读&#xff01;原文见&#xff1a;LeetCode 热题 100 回顾_力code热题100-CSDN博客 一、哈希部分 1.两数之和 &#xff08;简单&#xff09; 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标…

Rainbond 助力城建智控,从传统开发到敏捷开发转型

在现代企业的数字化转型过程中&#xff0c;如何高效管理和快速部署业务应用已经成为各行业的核心挑战。尤其是在智慧工地和办公自动化&#xff08;OA&#xff09;这样的关键业务场景中&#xff0c;企业不仅需要面对频繁的系统更新&#xff0c;还要确保系统的稳定性与高效运作。…

Python库matplotlib之五

Python库matplotlib之五 小部件(widget)RangeSlider构造器APIs应用实列 TextBox构造器APIs应用实列 小部件(widget) 小部件(widget)可与任何GUI后端一起工作。所有这些小部件都要求预定义一个Axes实例&#xff0c;并将其作为第一个参数传递。 Matplotlib不会试图布局这些小部件…

经典sql题(十二)UDTF之Explode炸裂函数

1. EXPLODE: UDTF 函数 1.1 功能说明 EXPLODE 函数 是Hive 中的一种用户定义的表函数&#xff08;UDTF&#xff09;&#xff0c;用于将数组或映射结构中的复杂的数据结构每个元素拆分为单独的行。这在处理复杂数据时非常有用&#xff0c;尤其是在需要将嵌套数据“打散”以便更…

测试面试题:pytest断言时,数据是符点类型,如何断言?

在使用 Pytest 进行断言时&#xff0c;如果数据是浮点类型&#xff0c;可以使用以下方法进行断言&#xff1a; 一、使用pytest.approx pytest.approx可以用来比较两个浮点数是否近似相等。例如&#xff1a; import pytestdef test_float_assertion():result 3.14159expecte…

OpenCV背景建模:从基础到实践

OpenCV中的背景建模是一种在计算机视觉中常用的技术&#xff0c;主要用于从视频或图像序列中分离出前景&#xff08;运动物体&#xff09;和背景。以下将详细介绍OpenCV中几种常见的背景建模方法&#xff1a; 1. 帧差法&#xff08;非直接称为backgroundSubtractor&#xff09…

探索高效免费的PDF转Word工具,开启便捷办公之旅

无论是为了方便对文档内容进行编辑、修改&#xff0c;还是为了更好地适应不同的工作和学习场景&#xff0c;将 PDF 文档转换为可编辑的 Word 格式都具有重要意义。今天我就分享几款pdf转换成word免费版工具来解决大家的困扰。 1.Foxit PDF转换大师 链接一下>>https://w…

Mirror | homebrew 镜像源配置

1. 详细步骤 1.1 临时使用 因为长期设置不知道为什么&#xff0c;可能会有不生效的情况&#xff0c;所以发现好像卡着 没有走清华源的时候&#xff0c;可以临时使用 # 设置清华镜像源&#xff1a;五行一起拷贝执行 export HOMEBREW_API_DOMAIN"https://mirrors.tuna.ts…

[ RK3566-Android11 ] 关于移植 RK628F 驱动以及后HDMI-IN图像延迟/无声等问题

问题描述 由前一篇文章https://blog.csdn.net/jay547063443/article/details/142059700?fromshareblogdetail&sharetypeblogdetail&sharerId142059700&sharereferPC&sharesourcejay547063443&sharefromfrom_link&#xff0c;移植HDMI-IN部分驱动后出现&a…

taobao.item_get_appAPI接口原app数据测试指南

在电商竞争日益激烈的当下&#xff0c;数据成为了商家们争夺市场的重要武器。淘宝&#xff0c;作为中国最大的在线零售平台&#xff0c;其庞大的商品库和用户群体为商家提供了巨大的商机。为了帮助商家更好地了解市场动态&#xff0c;优化库存和营销策略&#xff0c;淘宝推出了…

使用WebClient 快速发起请求(不使用WebClientUtils工具类)

使用WebClient发起网络请求_webclient工具类-CSDN博客文章浏览阅读717次&#xff0c;点赞9次&#xff0c;收藏8次。使用WebClient发起网络请求_webclient工具类https://blog.csdn.net/qq_43544074/article/details/137044825这个是使用工具类发起的&#xff0c;下面就不使用工具…

java基础(4)类和对象

目录 1.前言 2.正文 2.1类的定义与使用 2.1.1类的定义 2.1.2类的实例化 2.1.3this引用 2.1.3.1 访问当前对象的成员变量 2.1.3.2调用当前对象的成员方法 2.1.3.3构造函数中的 this 2.1.3.4归纳this 2.2封装 2.2.1封装的定义 2.2.2访问修饰符 2.3static 2.3.1sta…

Kevin‘s notes about Qt---Episode 6 不同类中创建同一对象

问题描述 使用场景 现在在我的Qt界面中需要同时使用采集卡的AI(Analog Input)和AO(Analog Output)功能,均已分别调通,但是像之前一样通过创建两个类,然后分别在两个线程中进行操作的方式并不能实现。 原本写法 头文件 art_ao.h 核心代码如下: #ifndef ART_AO_H #defi…

python自动更新chromedriver

python自动化过程中&#xff0c;经常遇到脚本跑着跑着&#xff0c;就报错&#xff0c;一看&#xff0c;浏览器自动升级了。 共两张解决方案&#xff1a; 1、禁止浏览器自动升级 2、当脚本运行前先去检测当前的chromedriver与浏览器是否匹配&#xff0c;不匹配&#xff0c;就下载…

“卷”智能, 从高质量算力开始

算力即国力&#xff0c;这已是产业共识。 当人工智能浪潮席卷全球之际&#xff0c;大家深刻感受到发展算力产业的重要性和紧迫性&#xff0c;高质量的人工智能算力已经与国家竞争、产业升级和企业转型息息相关。 去年&#xff0c;《算力基础设施高质量发展行动计划》的颁布&a…

前后端传参

文章目录 后端接收参数前端发送请求引入axios实现发送请求引入qs实现传参格式化axios基本写法 前后端传参将数组转化为单个Json字符串传输前端发送后端接收 将数组转换为json对象进行传输前端发送请求后端接受请求 直接传输数组前端发送请求后端接收请求 前后端发送请求格式需要…