当前位置: 首页 > news >正文

【Java NIO】

这里写目录标题

  • 为什么需要 NIO?传统 I/O 的局限性
    • 二级目录
      • 三级目录

Java I/O support is included in the java.io and java.nio packages. Together these packages include the following features:

  • Input and output through data streams, serialization and the file system.
  • Charsets, decoders, and encoders, for translating between bytes and Unicode characters.
  • Access to file, file attributes and file systems.
  • APIs for building scalable servers using asynchronous or multiplexed, non-blocking I/O.

为什么需要 NIO?传统 I/O 的局限性

  1. 阻塞式 I/O(BIO)的问题

  传统 InputStream/OutputStream 是同步阻塞模型:线程在读写数据时必须等待操作完成,无法处理其他任务。

import java.io.FileInputStream;
import java.io.InputStream;

public class BlockingExample {
    public static void main(String[] args) {
        try (InputStream is = new FileInputStream("large_file.txt")) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            
            // 同步阻塞点:read() 会阻塞直到数据读取完成
            while ((bytesRead = is.read(buffer)) != -1) { 
                System.out.println("读取到 " + bytesRead + " 字节数据");
                // 模拟处理数据(假设处理耗时)
                Thread.sleep(1000); 
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

代码解释
is.read(buffer) 是同步阻塞的:

  • 当调用 read() 方法时,线程会一直等待,直到从文件中读取到数据(或到达文件末尾)。

  • 如果文件很大或磁盘速度慢,线程会长时间阻塞在此处,无法执行其他任务。

整个过程是同步的:

  • 必须等待 read() 完成,才能进入下一次循环或处理数据(如 Thread.sleep(1000))。
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BlockingSocketServer {
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(8080)) {
            while (true) {
                // 同步阻塞点 1:accept() 阻塞,直到有客户端连接
                Socket clientSocket = serverSocket.accept(); 
                System.out.println("客户端连接:" + clientSocket.getRemoteSocketAddress());

                // 为每个客户端连接分配一个线程处理(传统 BIO 的典型做法)
                new Thread(() -> {
                    try (InputStream is = clientSocket.getInputStream()) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        
                        // 同步阻塞点 2:read() 阻塞,直到客户端发送数据
                        while ((bytesRead = is.read(buffer)) != -1) { 
                            String data = new String(buffer, 0, bytesRead);
                            System.out.println("收到数据:" + data);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  高并发场景下(如服务器处理大量连接),因为需要为每个连接分配独立线程,所以导致有大量的线程,导致线程资源耗尽和大量的CPU资源用于上下文切换开销。

  1. 内存映射与零拷贝的缺失

  传统 I/O 需要多次数据拷贝(用户态 ↔ 内核态),而 NIO 的 FileChannel 支持内存映射文件(MappedByteBuffer),减少拷贝次数,提升性能。

  1. 非阻塞与事件驱动需求

  传统 I/O 无法实现非阻塞操作,难以应对高并发、实时性要求高的场景(如聊天服务器、实时交易系统)。

二级目录

三级目录

http://www.dtcms.com/a/107220.html

相关文章:

  • 4.2学习总结 Java:list系列集合
  • 简单路径计数
  • 深度解析Python与ActiveMQ的完美交互
  • CF580B Kefa and Company(滑动窗口)
  • Java 连接 Redis 的驱动(Jedis、Lettuce、Redisson、Spring Data Redis)分类及对比
  • 尚语翻译图册翻译|专业图册翻译|北京专业翻译公司推荐|专业文件翻译报价
  • 开发体育赛事直播系统主播认证功能技术实现方案
  • 体重秤PCBA电路方案组成结构
  • 【CSS3】05-定位 + 修饰属性
  • XSS漏洞的分类解释和演示实验
  • dfs(基于BFS的dfs)力扣37.解数独力扣79.单词搜索力扣1219.黄金矿工力扣980.不同路径III
  • linux shell 删除空行(remove empty lines)
  • 12-leveldb优化读性能的方法
  • agent报告
  • Linux命令-inotifywait
  • 继承与组合
  • LlamaIndex实现RAG增强:融合检索(Fusion Retrieval)与混合检索(Hybrid Search)
  • [ 取证 ]取证学习,工具使用, 赛题复现
  • Day 6
  • 在Android中创建DialogFragment
  • 【光电集成电路技术】基于单片机的音乐梦幻灯与USB转接器设计,电子琴硬件组成及仿真电路实现
  • 【Java 优选算法】二分算法(下)
  • OpenGL进阶系列20 - OpenGL SuperBible - bindlesstex 例子学习
  • Flutter求助贴
  • 失效模式分析(FMEA)、控制计划(CP)、流程图(Flowchart)的无缝衔接与高效管理--全星FMEA软件系统
  • 《自然-方法》2024年度技术:空间蛋白质组学(spatial proteomics)
  • PyArrow 核心技术与应用:高效数据处理与跨生态集成实践
  • C语言常见3种排序
  • 利用vmware快速安装一个可以使用的centos7系统
  • QML弹窗