NIO学习笔记

1 简介

Java NIO是从java 1.4版本开始引入的一个新的IO API

  • 目的—替代标准版的Java IO API

NIO与原来的IO有同样的作用和目的,但是使用方式完全不同

  • NIO支持面向缓冲区的,基于通道的操作
  • NIO以更高效的方式进行文件的读写操作

2 与IO的主要区别

IO

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

3 通道和缓冲区

NIO系统的核心在于:

  • 通道(Channel)—打开到IO设置(例如:文件, 套接字)连接
  • 缓冲区(Buffer)—一个用于特定基本数据类型的容器
    由java.nio包定义,所有缓冲区都是Buffer抽象类的子类

若需要使用NIO系统

  • 需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区.
  • 然后操作缓冲区,对数据进行处理

简而言之, Channel负责传输,Buffer负责存储

3.1 缓冲区

缓冲区(Buffer):在Java NIO中负责数据的存取. 缓冲区就是数组,用于存储不同数据类型的数据

根据数据类型不同(Boolean除外),提供了相应的缓冲区

  • ByteBuffer
  • CharBuffer
  • ShortBuffer
  • IntBuffer
  • LongBuffer
  • FloatBuffer
  • DoubleBuffer

上述缓冲区的管理方式几乎一致,通过allocate获取缓冲区

缓冲区存取数据的两个核心方法

  • put()—存入数据到缓冲区中
  • get()—获取缓冲区中的数据

缓冲区中的四个核心属性

  • capacity—容量,标识缓冲区最大存储数据的容量,一旦声明就不能改变
  • limit—界限,表示缓冲区中可以操作数据的大小limit后面的数据不能读写
  • position—位置,表示缓冲区中正在操作数据的位置
    position <= limit <= capacity
  • mark—标记, 表示记录当前position的位置,可以通过reset()恢复到mark位置
    0 <= mark <= position <= capacity

3.2 直接缓冲区与非直接缓冲区

  • 非直接缓冲区—通过allocate()方法分配缓冲区,将缓冲区建立在JVM的内存中
  • 直接缓冲区—通过allocateDirect()方法分配直接缓冲区,将缓冲区建立在物理内存中,可以提高效率

字节缓冲区要么是直接的,要么是非直接的. 如果为直接字节缓冲区,则JVM会尽最大努力直接在此缓冲区上执行本机的I/O操作

也就是说,在每次调用基础操作系统的一个本机I/O操作之前(或之后),虚拟机都会尽量避免将缓冲区中的内容复制到中间缓冲区中(或从中间缓冲区中复制内容)

直接字节缓冲区可以通过调用此类的allocateDirect()方法来创建. 此方法返回的缓冲区进行分配和取消分配所需成本通常高于非直接缓冲区. 直接缓冲区的内容可以在主流在常规的垃圾回收器之外. 因此, 他们对应用程序的内容需求量造成的影响可能并不明显. 所以, 建议将直接缓冲区主要分配给哪些容易受基础系统的本机I/O操作影响的大型, 持久的缓冲区.

一般情况下,最好仅在直接缓冲区能在程序性能方面带来明显好处时分配它们

直接缓冲区还可以通过FileChannel的map()方法将文件区域直接映射到内存中来创建. 该方法返回MappedByteBuffer.

Java平台的实现有助于通过JNI从本机代码创建直接字节缓冲区.

如果以上这些缓冲区中某个缓冲区实例指的是不可用访问的内存区域,则试图访问该区域不会更改该缓冲区的内容.并且将会在访问期间或稍后的某个时间导致抛出不确定的异常

字节缓冲区是直接缓冲区还是非直接缓冲区可以通过其isDirect()方法来确定.提供此方法是为了能够在性能关键代码中执行显示缓冲区管理

如下图所示
非直接缓冲区

直接缓冲区

3.3 通道

通道(Channel)—由java.nio.channels包定义的
Channel表示IO源与目标打开的连接

用于源节点和目标节点的连接, 在Java NIO中负责缓冲区中的数据传输. Channel本身不存储数据,因此需要配合缓冲区进行传输

Channel类似于传统的"流", 只不过Channel本身不能直接访问数据,Channel只能与Buffer进行交互

CPU直接处理I/O请求
CPU直接处理I/O请求
通过DMA—直接存储器处理IO请求
通过DMA---直接存储器处理IO请求
通过通道处理IO请求
通过通道处理IO请求

3.3.1 主要实现类

java.nio.channels.Channel接口

  • FileChannel—文件传输
  • SocketChannel—网络传输(客户端)
  • ServerSocketChannel—网络传输(服务端)
    -DatagramChannel—网络传输, UDP

获取通道

  1. Java针对支持通道的类提供了getChannel()方法
  • 本地IO
    • FileInputStream/FileOutputStream
    • RandomAccessFile
  • 网络IO
    • Socket
    • ServerSocket
    • DatagramSocket
  1. 在JDK 1.7中的NIO针对各个通道提供了静态方法open()
  2. 在JDK 1.7中的Files工具类的newByteChannel()
  3. 通道之间的数据传输
    • transferFrom
    • transferTo
      两者也是通过直接缓冲区传递数据

3.4 分散(Scatter)和聚集(Gather)

  • 分散读取Scatter Reads是指从Channel中读取的数据分散到各个Buffer中

注意: 按照缓冲区的顺序,从Channel中读取的数据依次将Buffer填满

  • 聚集写入Gather Writes是指将多个Buffer中的数据"聚集"到Channel

注意: 按照缓冲区的顺序,写入position和limit之间的数据到Channel

3.5.字符集

Charset

  • 编码—字符串 —> 字节数组
  • 解码—字节数组 —>字符串

4 NIO非阻塞式

4.1 阻塞与非阻塞

传统的的IO流都是阻塞的. 也就是说,当一个线程调用read()或write()时,该线程被阻塞, 直到有一些数据被读取或写入, 该线程在此期间不能执行其他任务.

因此, 在完成网络通信进行IO操作时, 由于线程会阻塞, 所以服务器补习为每个客户端都提供一个独立的线程进行处理, 当服务端需要处理大量客户端时, 性能急剧下降


Java NIO是非阻塞式的. 当线程从某通道进行读写数据时, 若没有数据可用时, 该线程可以进行其他任务, 线程通常将非阻塞IO的空闲时间用于在其他通道上执行IO操作, 所以单独的线程可以管理多个输入和输出通道

因此, NIO可以让服务端使用一个或有限几个线程来同时处理连接到服务器端的所有客户端

4.2 NIO

使用NIO完成网络通信的三个核心

  • 通道(Channel)—负责连接
  • 缓冲区(Buffer)—负责数据的存储
  • 选择器(Selector)—是SelectableChannel的多路复用器
    用于监控SelectableChannel的IO状况

4.3 选择器

选择器(Selector)是SelectableChannel对象的多路复用器

Selector可以同时监控多个SelectableChannel的状态, 也就是说, 利用Selector可以使一个单独的线程管理多个Channel. Selector是非阻塞IO的核心

SelectableChannel的结构如下:

  • SelectableChannel
    • AbstractSelectableChannel
      • SocketChannel
      • ServerSocketChannel
      • DatagramChannel

4.3.1 SelectionKey

  • 当调用register(Selector sel, int pos) 将通道注册选择器时, 选择器对通道的监听事件,需要通过第二个参数ops指定

  • 可以监听的事件类型(可使用SelectionKey的四个常量表示)

    • 读—SelectionKey.OP_READ
    • 写—SelectionKey.OP_WRITE
    • 连接—SelectionKey.OP_CONNECT
    • 接收—SelectionKey.OP_ACCEPT

若注册时不止监听一个事件,则可以使用"位或"操作符连接

【SCI一区复现】基于配电网韧性提升的应急移动电源预配置和动态调度(下)—MPS动态调度(Matlab代码实现)内容概要:本文档围绕“基于配电网韧性提升的应急移动电源预配置和动态调度”主题,重点介绍MPS(Mobile Power Sources)动态调度的Matlab代码实现,是SCI一区论文复现的技术资料。内容涵盖在灾害或故障等极端场景下,如何通过优化算法对应急移动电源进行科学调度,以提升配电网在突发事件中的恢复能力与供电可靠性。文档强调采用先进的智能优化算法进行建模求解,并结合IEEE标准测试系统(如IEEE33节点)进行仿真验证,具有较强的学术前沿性和工程应用价值。; 适合人群:具备电力系统基础知识和Matlab编程能力,从事电力系统优化、配电网韧性、应急电源调度等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①用于复现高水平期刊(SCI一区、IEEE顶刊)中关于配电网韧性与移动电源调度的研究成果;②支撑科研项目中的模型构建与算法开发,提升配电网在故障后的快速恢复能力;③为电力系统应急调度策略提供仿真工具与技术参考。; 阅读建议:建议结合前篇“MPS预配置”内容系统学习,重点关注动态调度模型的数学建模、目标函数设计与Matlab代码实现细节,建议配合YALMIP等优化工具包进行仿真实验,并参考文中提供的网盘资源获取完整代码与数据。
一款AI短视频生成工具,只需输入一句产品卖点或内容主题,软件便能自动生成脚本、配音、字幕和特效,并在30秒内渲染出成片。 支持批量自动剪辑,能够实现无人值守的循环生产。 一键生成产品营销与泛内容短视频,AI批量自动剪辑,高颜值跨平台桌面端工具。 AI视频生成工具是一个桌面端应用,旨在通过AI技术简化短视频的制作流程。用户可以通过简单的提示词文本+视频分镜素材,快速且自动的剪辑出高质量的产品营销和泛内容短视频。该项目集成了AI驱动的文案生成、语音合成、视频剪辑、字幕特效等功能,旨在为用户提供开箱即用的短视频制作体验。 核心功能 AI驱动:集成了最新的AI技术,提升视频制作效率和质量 文案生成:基于提示词生成高质量的短视频文案 自动剪辑:支持多种视频格式,自动化批量处理视频剪辑任务 语音合成:将生成的文案转换为自然流畅的语音 字幕特效:自动添加字幕和特效,提升视频质量 批量处理:支持批量任务,按预设自动持续合成视频 多语言支持:支持中文、英文等多种语言,满足不同用户需求 开箱即用:无需复杂配置,用户可以快速上手 持续更新:定期发布新版本,修复bug并添加新功能 安全可靠:完全本地本地化运行,确保用户数据安全 用户友好:简洁直观的用户界面,易于操作 多平台支持:支持Windows、macOS和Linux等多个操作系统
源码来自:https://pan.quark.cn/s/2bb27108fef8 **MetaTrader 5的智能交易系统(EA)**MetaTrader 5(MT5)是由MetaQuotes Software Corp公司研发的一款广受欢迎的外汇交易及金融市场分析软件。 该平台具备高级图表、技术分析工具、自动化交易(借助EA,即Expert Advisor)以及算法交易等多项功能,使交易参与者能够高效且智能化地开展市场活动。 **抛物线SAR(Parabolic SAR)技术指标**抛物线SAR(Stop and Reverse)是由技术分析专家Wells Wilder所设计的一种趋势追踪工具,其目的在于识别价格走势的变动并设定止损及止盈界限。 SAR值的计算依赖于当前价格与前一个周期的SAR数值,随着价格的上扬或下滑,SAR会以一定的加速系数逐渐靠近价格轨迹,一旦价格走势发生逆转,SAR也会迅速调整方向,从而发出交易提示。 **Parabolic SAR EA的操作原理**在MetaTrader 5环境中,Parabolic SAR EA借助内嵌的iSAR工具来执行交易决策。 iSAR工具通过计算得出的SAR位置,辅助EA判断入市与离市时机。 当市场价位触及SAR点时,EA将产生开仓指令,倘若价格持续朝同一方向变动,SAR将同步移动,形成动态止损与止盈参考点。 当价格反向突破SAR时,EA会结束当前仓位并可能建立反向仓位。 **智能交易系统(EA)的优越性**1. **自动化交易**:EA能够持续监控市场,依据既定策略自动完成买卖操作,减少人为情感对交易的影响。 2. **精确操作**:EA依照预设规则操作,无任何迟疑,从而提升交易成效。 3. **风险管控**:借助SA...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值