热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

NIO通道接口详解

本文介绍了NIO(NewInput/Output)中的通道接口及其相关概念,包括通道的基本功能、接口设计以及各类通道接口的具体用途。通过本文,读者可以深入了解NIO通道的设计原理及其在实际项目中的应用。

一、通道概述


在探讨NIO的通道之前,我们已经介绍了缓冲区的相关知识。缓冲区可以视为客户端操作数据的临时存储区,而通道则是数据传输的路径。通道负责在不同的端点之间传输数据,就像船舶和航线负责将货物从一个港口运送到另一个港口一样。到达目的港的数据可能会被消费,也可能被进一步传输到下一个目的地。


单独讨论缓冲区的意义不大,NIO的核心在于解决数据在不同客户端之间的高效传输问题。因此,NIO在设计通道时考虑了更多的复杂性。然而,在实际项目中,常用的通道类型相对有限。本文将分为两部分介绍:一是通道的接口设计,二是NIO已实现的通道类型及其使用说明。



二、通道接口设计


NIO的通道设计采用了大量的功能抽象,具体可用的通道类的特性由其实现的接口决定。因此,要深入理解NIO的通道设计,首先需要了解整个NIO通道体系的接口设计。需要注意的是,虽然接口定义了实现类的行为,但具体行为的细节仍取决于具体的实现类。


以下是NIO通道接口的派生关系图:


NIO通道接口UML



三、接口说明


本文不会对每个接口进行详细的说明,因为从接口定义本身很难看出具体方法的行为。JDK在接口方法的注释中提供了一些实现类需要注意的点,但大部分书籍和文章也只是翻译了这些注释。下面是一些主要接口的简介:



3.1 AutoCloseable


这个接口是JDK 1.7引入的,支持try-with-resources语法,解决了finally块中关闭资源时的异常覆盖问题。这意味着所有实现Channel接口的类都具备自动关闭的特性。


例如,使用传统的try-finally块关闭资源时,可能会丢失最初的异常信息:


public class ExceptionTest implements AutoCloseable {
public static void main(String[] args) throws Exception {
ExceptionTest exceptiOnTest= null;
try {
exceptiOnTest= new ExceptionTest();
exceptionTest.open(); // 注意open会抛出异常
} finally {
try {
if (exceptionTest != null) {
exceptionTest.close(); // open异常后执行close,close继续抛出异常
}
} catch (Exception e) {
e.printStackTrace(); // open的异常就丢失了
}
}
}

public void open() throws IOException {
System.out.println("invoke open method");
throw new IOException("open method exception");
}

public void close() throws Exception {
System.out.println("invoke close method");
throw new IOException("close method exception");
}
}

使用try-with-resources语法可以避免这种情况:


public class ExceptionTest implements AutoCloseable {
public static void main(String[] args) throws Exception {
try (ExceptionTest exceptiOnTest= new ExceptionTest()) {
exceptionTest.open();
}
}

public void open() throws IOException {
System.out.println("invoke open method");
throw new IOException("open method exception");
}

public void close() throws Exception {
System.out.println("invoke close method");
throw new IOException("close method exception");
}
}


3.2 Closeable


这是一个古老的接口,用于支持可显式关闭的资源,最早出现在JDK 1.5中,并在JDK 1.7中扩展为实现AutoCloseable接口。这意味着所有通道都支持自动关闭和显式关闭。



3.3 Channel


这是最基本的通道接口,定义了通道必须支持的基本操作,如关闭和检查通道是否打开。Channel接口中的isOpen方法用于检查通道是否处于打开状态。



3.4 InterruptibleChannel


这个接口没有定义新的方法,但通过注释说明了其用途。InterruptibleChannel表示一个可中断的通道。如果应用程序线程在该类型的通道上阻塞,当通道关闭时,线程会收到AsynchronousCloseException异常。此外,如果其他线程调用该通道的interrupt方法,通道会被关闭,当前线程会收到AsynchronousCloseException异常并进入中断状态。



3.5 ReadableByteChannel


这个接口提供了从通道读取数据的方法。需要注意的是,当前线程读取数据时,其他线程的读操作会被阻塞。由于涉及操作系统底层的数据传输,因此仅支持字节读取。



3.6 ScatteringByteChannel


这是ReadableByteChannel的直接子接口,扩展了字节读取操作,允许将通道中的数据读取到多个缓冲区中。



3.7 WritableByteChannel


与ReadableByteChannel相对,这个接口提供了向通道写入数据的方法。当前线程写入数据时,其他线程的写操作会被阻塞。



3.8 GatheringByteChannel


这是WritableByteChannel的子接口,允许多个缓冲区向通道中写入数据。



3.9 ByteChannel


这个接口结合了字节读取和写入操作,实现该接口的类可以同时支持读写操作。



3.10 SeekableByteChannel


这个接口扩展了ByteChannel,增加了对位置(position)的维护操作,允许在通道中进行随机访问。



3.11 AsynchronousChannel


这是实现异步I/O操作的核心接口,实现了该接口的通道是线程安全的,允许并发读写。但需要注意的是,不允许在一个I/O操作未完成的情况下再次进行读写操作。



3.12 AsynchronousByteChannel


在AsynchronousChannel接口的基础上,扩展了以字节为单位的读写操作。



3.13 NetworkChannel


这是一个非常重要的接口,支持Socket的数据读写操作,将通道中的数据与Socket关联起来,是网络NIO实现的关键接口。



3.14 MulticastChannel


这个接口支持IP多播,将多个IP地址打包成一个组,然后将数据包发送到组内的所有主机。



四、结语


本文详细介绍了NIO通道接口及其设计原理,希望对读者理解和使用NIO通道有所帮助。如果想了解更多硬技能的分享,可以参考“积少成多”系列传送门,未来每一篇关于硬技能的文章都会在传送门中更新链接。


推荐阅读
  • c++:1
    C第一部分介绍基础:c++:-0,本节介绍C中函数使用。##函数###函数调用调用函数需要先声明函数原型嵌套调用:###参数传递在函数被调用时才分配形参的存储单元实参可以是常量、变 ... [详细]
  • 本文详细解析了muduo库中的Socket封装及字节序转换功能。主要涉及`Endian.h`和`SocketsOps.h`两个头文件,以及`Socket.h`和`InetAddress.h`类的实现。 ... [详细]
  • Elasticsearch集群构建指南:本地环境搭建与管理
    本文详细介绍了如何在本地环境中搭建Elasticsearch集群,包括节点配置、主节点选举机制、以及如何通过单播和广播方式增加节点。同时,文章还探讨了集群的高可用性和扩展性,以及如何通过配置防止脑裂现象的发生。 ... [详细]
  • 应用场景在开发中,我们经常需要把一些随时可能变化的属性配置到配置文件中,这样耦合性低,方便维护。SpringBoot在这方面为我们提供了很大的便捷,我们可以很轻易的将propert ... [详细]
  • MQTT协议:轻量级消息传输的基石
    MQTT(Message Queuing Telemetry Transport,消息队列遥测传输)是一种基于发布/订阅模式的轻量级通信协议,适用于低带宽、高延迟或不可靠的网络环境。该协议基于TCP/IP构建,由IBM在1999年首次推出,旨在通过最小化网络流量和代码量,为远程设备提供高效、可靠的消息传输服务。 ... [详细]
  • 本文详细解析了Java面试中常见的问题及答案,旨在帮助求职者更好地准备面试,提高通过率。 ... [详细]
  • 深入探讨PHP中的输出缓冲技术(Output Buffering)
    本文深入解析了PHP中输出缓冲(Output Buffering)的原理及其在Web开发中的应用,特别是如何通过输出缓冲技术有效管理HTTP头部信息,提高代码的灵活性与健壮性。 ... [详细]
  • 本文详细介绍了如何使用 Element UI 的 Cascader 组件来实现省、市、区数据的动态加载。主要通过地址传递和递归函数来动态更新选项列表。 ... [详细]
  • socket函数SOCKET()我们使用系统调用socket()来获得文件描述符:#include#includei ... [详细]
  • 优化 DropDownList 与 TextBox 的交互体验
    本文介绍了一种解决方案,通过在 DropDownList 前添加一个 TextBox 来提升用户体验。当选项过多时,用户可以通过在 TextBox 中输入关键词来快速定位并选择相应的选项。 ... [详细]
  • Flask框架下MySQL数据库的集成与应用
    本文详细探讨了如何在Flask框架中集成和使用MySQL数据库,通过具体的实例和代码演示,帮助开发者更好地理解和掌握Flask与MySQL的结合使用。 ... [详细]
  • 一、搭建项目创建Maven项目导入rabbitmq包com.rabbitmqamqp-clien ... [详细]
  • MD5(Message-Digest Algorithm 5),即消息摘要算法第五版,是一种广泛应用于计算机安全领域的散列函数,主要用于确保数据传输的完整性和验证数据的一致性。本文将介绍如何在Java编程环境中实现MD5加密。 ... [详细]
  • 本文探讨了字节数组流的应用,特别是在内存和网络数据处理中的优势。不同于传统的文件字节流和字符流,字节数组流的数据源来自内存或网络,适用于网络传输等场景。文章还详细介绍了字节数组输入流和输出流的特点及使用方法,并提供了流对接的实践案例。 ... [详细]
  • 本文详细探讨了Laravel框架中的数据库操作,包括读写分离、事务处理、Eloquent ORM的使用、关联关系管理及性能优化技巧。 ... [详细]
author-avatar
mobiledu2502911797
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有