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

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

标题Python网络课程在线学习平台研究AI更换标题第1章引言介绍Python网络课程在线学习平台的研究背景、意义、国内外现状和研究方法。1.1研究背景与意义阐述Python在线学习平台的重要性和研究意义。1.2国内外研究现状概述国内外Python在线学习平台的发展现状。1.3研究方法与论文结构介绍本文的研究方法和整体论文结构。第2章相关理论总结在线学习平台及Python教育的相关理论。2.1在线学习平台概述介绍在线学习平台的基本概念、特点和发展趋势。2.2Python教育理论阐述Python语言教学的理论和方法。2.3技术支持理论讨论构建在线学习平台所需的技术支持理论。第3章Python网络课程在线学习平台设计详细介绍Python网络课程在线学习平台的设计方案。3.1平台功能设计阐述平台的核心功能,如课程管理、用户管理、学习跟踪等。3.2平台架构设计给出平台的整体架构,包括前后端设计、数据库设计等。3.3平台界面设计介绍平台的用户界面设计,强调用户体验和易用性。第4章平台实现与测试详细阐述Python网络课程在线学习平台的实现过程和测试方法。4.1平台实现介绍平台的开发环境、技术栈和实现细节。4.2平台测试对平台进行功能测试、性能测试和安全测试,确保平台稳定可靠。第5章平台应用与效果分析分析Python网络课程在线学习平台在实际应用中的效果。5.1平台应用案例介绍平台在实际教学或培训中的应用案例。5.2效果评估与分析通过数据分析和用户反馈,评估平台的应用效果。第6章结论与展望总结Python网络课程在线学习平台的研究成果,并展望未来发展方向。6.1研究结论概括本文关于Python在线学习平台的研究结论。6.2研究展望提出未来Python在线学习平台的研究方向和发展建议。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值