Java NIO 概述(Channel、Buffer、Selector)

简介: Java NIO (New IO 或 Non Bloking IO) 是从 Java 1.4 版本开始引入一个新的 IO API, 可以替代标准的 Java IO API。NIO 全面支持面向缓冲区的、基于通道的 IO 操作。NIO 将以高效的方式进行文件的读写操作。

阻塞 IO


通常在进行同步 I/O 操作时,如果读取数据,代码会阻塞直至有可供读取的数据。同样,写入调用将会阻塞直至数据能够写入。传统的 Server/Client 模式会基于 TPR (Thread per Request ), 服务器会为每个客户端请求建立一个线程,由该线程单独负责处理一个客户请求。这种模式带来的问题就是线程数量的急剧增加,大量的线程会增大服务的开销。大多数的实现为了避免这个问题,采用了线程池模型,并设置线程池的最大数量,这个带来了新的问题,如果线程池中有 100 个线程,而有 100个用户都在进行大文件下载,会导致 101 个用户的请求无法及时处理,即便第 101 个用户指向请求一个几 kb 大小的页面。传统的 Server /Client 模式如下图所示


image.png


非阻塞 IO(NIO)


NIO 中非阻塞 I/O 采用了基于 Reactor 模式的工作方式, I/O 调用不会被阻塞, 相反是注册感兴趣的 I/O 事件,如可读数据到达,新的套接字连接等等,在发生特定的事件时,系统再通知我们。NIO 中实现非阻塞 I/O 的核心对象就是 Selector 。


Selector 就是注册各种 I / O 时间地方,而且当我们感兴趣的事件发生时,就是这个对象告诉我们发生的事件,如下图所示:


image.png


从图中可以看到,当有读,或者写等任何注册事件发生时,可以从 Selector 中获取响应的 SelectionKey , 同事从 SelectorKey 中恶意找到发生的事件和该事件所发生的具体 SelectableCannel 以获取客户端发送过来的数据。


非阻塞指的是 IO 本身不阻塞,但是获取 IO 事件的 select() 方法是需要阻塞等待的。区别阻塞的 IO 会阻塞在 IO 操作上,NIO 阻塞在事件获取上,没有事件就没有 IO , 从高层次来看 IO 就不阻塞了,也就是说只有 IO 已经发生那么我们才评估 IO 是否阻塞,但是 select() 阻塞的时候 IO 还没有发生,何谈 IO 的阻塞呢? NIO的本质是延迟 IO 操作到真正发生 IO的时候,而不是以前只要 IO 流打开就一直等待 IO 操作。


总结:NIO 不会发生 IO 打开后阻塞,而是在 IO 发生的时候会处理,其实本质也是一种 IO 延迟阻塞。


IO NIO
面向流(Stream Oriented) 面向缓冲区(Buffer Oriented)
阻塞IO(Blocking IO) 非阻塞IO(Non Blocking IO)
(无) 选择器(Selector)


NIO 概述


Java NIO 由一下几个核心部分组成:


  • Channels


  • Buffers


  • Selectors


虽然 Java NIO 中除此之外还有很多类和组件,单 Channel, Buffer 和 Selector 构成了核心的 API 。其他组件,如 Pipe 和 FileLock , 只不过是与三个核心组件共同协作的工具类。


Channel


首先说下 Channel ,可以翻译为 “通道”Channel 和 IO 的Stream (流)是差不多的一个等级的。只是 Stream 是单向的,比如 InputStream , OutputStream. 而 Channel 是双向的,既可以用来进行读操作,又可以用来进行写操作。


NIO 中的 Channel 的主要实现有:FileChannel、DatagramChannel 、SocketChannel 和 ServerSocketChannel , 这里看名字就可以猜出来: 分别对应文件 IO 、UDP 和 TCP (Server 和 Client)。


Buffer


NIO 找那个关键 Buffer 实现有:ByteBuffer , CharBuffer , DoubleBuffer , FloatBuffer, IntBuffer, LongBuffer, ShortBUffer , 分别对应基本数据类型 : byte , char , dubbole, float , int , long , short.


Selector


Selector 运行单线程处理多个 Channel , 如果你的引用中开启了多个通道,但是每个连接的流量都很低,使用 Selector 就会很方便,例如在一个聊天服务器中,要使用 Selector, 需要向 Selector 中注册 Channel , 然后调用 select() 方法。 这个方法一直会阻塞到其注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有:新的连接进来、数据接收等。


相关文章
|
4月前
|
Java 大数据
解析Java中的NIO与传统IO的区别与应用
解析Java中的NIO与传统IO的区别与应用
|
17天前
|
Java
让星星⭐月亮告诉你,Java NIO之Buffer详解 属性capacity/position/limit/mark 方法put(X)/get()/flip()/compact()/clear()
这段代码演示了Java NIO中`ByteBuffer`的基本操作,包括分配、写入、翻转、读取、压缩和清空缓冲区。通过示例展示了`position`、`limit`和`mark`属性的变化过程,帮助理解缓冲区的工作原理。
21 2
|
2月前
|
存储 网络协议 Java
Java NIO 开发
本文介绍了Java NIO(New IO)及其主要组件,包括Channel、Buffer和Selector,并对比了NIO与传统IO的优势。文章详细讲解了FileChannel、SocketChannel、ServerSocketChannel、DatagramChannel及Pipe.SinkChannel和Pipe.SourceChannel等Channel实现类,并提供了示例代码。通过这些示例,读者可以了解如何使用不同类型的通道进行数据读写操作。
Java NIO 开发
|
26天前
|
缓存 Java
java文件读取 while ((len = reader.read(buffer)) != -1){}的理解
本文解释了Java中使用`InputStreamReader`和`read(buffer)`方法循环读取文件内容的机制,强调了如何正确理解读取循环和处理读取到的数据,以及如何处理字符编码和换行符。
31 0
|
3月前
|
Java
"揭秘Java IO三大模式:BIO、NIO、AIO背后的秘密!为何AIO成为高并发时代的宠儿,你的选择对了吗?"
【8月更文挑战第19天】在Java的IO编程中,BIO、NIO与AIO代表了三种不同的IO处理机制。BIO采用同步阻塞模型,每个连接需单独线程处理,适用于连接少且稳定的场景。NIO引入了非阻塞性质,利用Channel、Buffer与Selector实现多路复用,提升了效率与吞吐量。AIO则是真正的异步IO,在JDK 7中引入,通过回调或Future机制在IO操作完成后通知应用,适合高并发场景。选择合适的模型对构建高效网络应用至关重要。
67 2
|
3月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
98 0
|
4月前
|
安全 Java Linux
(七)Java网络编程-IO模型篇之从BIO、NIO、AIO到内核select、epoll剖析!
IO(Input/Output)方面的基本知识,相信大家都不陌生,毕竟这也是在学习编程基础时就已经接触过的内容,但最初的IO教学大多数是停留在最基本的BIO,而并未对于NIO、AIO、多路复用等的高级内容进行详细讲述,但这些却是大部分高性能技术的底层核心,因此本文则准备围绕着IO知识进行展开。
147 1
|
3月前
|
存储 网络协议 Java
【Netty 神奇之旅】Java NIO 基础全解析:从零开始玩转高效网络编程!
【8月更文挑战第24天】本文介绍了Java NIO,一种非阻塞I/O模型,极大提升了Java应用程序在网络通信中的性能。核心组件包括Buffer、Channel、Selector和SocketChannel。通过示例代码展示了如何使用Java NIO进行服务器与客户端通信。此外,还介绍了基于Java NIO的高性能网络框架Netty,以及如何用Netty构建TCP服务器和客户端。熟悉这些技术和概念对于开发高并发网络应用至关重要。
63 0
|
4月前
|
安全 Java
【Java】已解决java.nio.channels.OverlappingFileLockException异常
【Java】已解决java.nio.channels.OverlappingFileLockException异常
104 1
|
4月前
|
Java
【Java】已解决java.nio.channels.ClosedChannelException异常
【Java】已解决java.nio.channels.ClosedChannelException异常
326 1