Java NIO之Selector类与SelectableChannel类

java selector类的用法举例 java nio中selector选择器的使用说明文档 立即下载

Selector类

简介

Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

官方文档的解释:SelectableChannel 对象的多路复用器 可通过调用此类的 open 方法创建选择器,该方法将使用系统的默认选择器提供者创建新的选择器。也可通过调用自定义选择器提供者的 openSelector 方法来创建选择器。通过选择器的 close 方法关闭选择器之前,它一直保持打开状态。

主要方法
public static Selector open()
                     throws IOException打开一个选择器。 
通过调用系统级默认 SelectorProvider 对象的 openSelector 方法来创建新的选择器。 


返回:
新的选择器 
抛出: 
IOException - 如果发生 I/O 错误
selectedKeys
public abstract Set<SelectionKey> selectedKeys()返回此选择器的已选择键集。 
可从已选择键集中移除键,但是无法直接添加键。试图向该键集中添加对象会导致抛出 UnsupportedOperationException。 

已选择键集是非线程安全的。 


返回:
此选择器的已选择键集 
抛出: 
ClosedSelectorException - 如果此选择器已关闭
select
public abstract int select(long timeout)
                    throws IOException选择一组键,其相应的通道已为 I/O 操作准备就绪。 
此方法执行处于阻塞模式的选择操作。仅在至少选择一个通道、调用此选择器的 wakeup 方法、当前的线程已中断,或者给定的超时期满(以先到者为准)后此方法才返回。 

此方法不提供实时保证:它安排了超时时间,就像调用 Object.wait(long) 方法一样。 


参数:
timeout - 如果为正,则在等待某个通道准备就绪时最多阻塞 timeout 毫秒;如果为零,则无限期地阻塞;必须为非负数 
返回:
已更新其准备就绪操作集的键的数目,该数目可能为零 
抛出: 
IOException - 如果发生 I/O 错误 
ClosedSelectorException - 如果此选择器已关闭 
IllegalArgumentException - 如果 timeout 参数的值为负
close
public abstract void close()
                    throws IOException关闭此选择器。 
如果某个线程目前正阻塞在此选择器的某个选择方法中,则中断该线程,如同调用该选择器的 wakeup 方法那样。 

所有仍与此选择器关联的未取消键已无效、其通道已注销,并且与此选择器关联的所有其他资源已释放。 

如果此选择器已经关闭,则调用此方法无效。 

关闭选择器后,除了调用此方法或 wakeup 方法外,以任何其他方式继续使用它都将导致抛出 ClosedSelectorException。 


抛出: 
IOException - 如果发生 I/O 错误

SelectableChannel

简介

可通过 Selector 实现多路复用的通道。

为了与选择器一起使用,此类的实例必须首先通过 register 方法进行注册。此方法返回一个表示该通道已向选择器注册的新 SelectionKey 对象。

向选择器注册后,通道在注销 之前将保持注册状态。注销涉及释放选择器已分配给该通道的所有资源。

不能直接注销通道;相反,必须取消 表示通道注册的键。取消某个键要求在选择器的下一个选择操作期间注销通道。可通过调用某个键的 cancel 方法显式地取消该键。无论是通过调用通道的 close 方法,还是中断阻塞于该通道上 I/O 操作中的线程来关闭该通道,都会隐式地取消该通道的所有键。

如果选择器本身已关闭,则将注销该通道,并且表示其注册的键将立即无效。

一个通道至多只能在任意特定选择器上注册一次。

可通过调用 isRegistered 方法来确定是否向一个或多个选择器注册了某个通道。

多个并发线程可安全地使用可选择的通道。

主要方法
register
public abstract SelectionKey register(Selector sel,
                                      int ops,
                                      Object att)
                               throws ClosedChannelException向给定的选择器注册此通道,返回一个选择键。 
如果当前已向给定的选择器注册了此通道,则返回表示该注册的选择键。该键的相关操作集将更改为 ops,就像调用 interestOps(int) 方法一样。如果 att 参数不为 null,则将该键的附件设置为该值。如果已取消该键,则抛出 CancelledKeyException。 

如果尚未向给定的选择器注册此通道,则注册该通道并返回得到的新键。该键的初始可用操作集是 ops,并且其附件是 att。 

可在任意时间调用此方法。如果调用此方法的同时正在进行另一个此方法或 configureBlocking 方法的调用,则在另一个操作完成前将首先阻塞该调用。然后此方法将在选择器的键集上实现同步,因此如果调用此方法时并发地调用了涉及同一选择器的另一个注册或选择操作,则可能阻塞此方法的调用。 

如果正在进行此操作时关闭了此通道,则此方法返回的键是已取消的,因此返回键无效。 


参数:
sel - 要向其注册此通道的选择器
ops - 所得键的可用操作集
att - 所得键的附件,可能为 null 
返回:
表示此通道向给定选择器注册的键 
抛出: 
ClosedChannelException - 如果此通道已关闭 
IllegalBlockingModeException - 如果此通道处于阻塞模式 
IllegalSelectorException - 如果此通道与给定的选择器不是由相同的提供者创建的 
CancelledKeyException - 如果此通道当前已向给定的选择器注册,但是相应的键已经被取消 
IllegalArgumentException - 如果 ops 集的某个位不对应于此通道所支持的某个操作,也就是说,如果 set & ~validOps() != 0
configureBlocking
public abstract SelectableChannel configureBlocking(boolean block)
                                             throws IOException调整此通道的阻塞模式。 
如果向一个或多个选择器注册了此通道,则尝试将此通道置于阻塞模式将导致抛出 IllegalBlockingModeException。 

可在任意时间调用此方法。新的阻塞模式仅影响在此方法返回后发起的 I/O 操作。对于某些实现而言,这可能需要在所有挂起的 I/O 操作完成之前阻塞其他操作。 

如果调用此方法的同时正在进行另一个此方法或 register 方法的调用,则在另一个操作完成前将首先阻塞该调用。 


参数:
block - 如果为 true,则此通道将被置于阻塞模式;如果为 false,则此通道将被置于非阻塞模式 
返回:
此可选择通道 
抛出: 
ClosedChannelException - 如果此通道已关闭 
IllegalBlockingModeException - 如果 block 为 true 并且此通道已向一个或多个选择器注册 
IOException - 如果发生 I/O 错误

selector的使用

创建选择器

通过 Selector.open()方法, 我们可以创建一个选择器:

Selector selector = Selector.open();
将 Channel 注册到选择器中

为了使用选择器管理 Channel, 我们需要将 Channel 注册到选择器中:

channel.configureBlocking(false);

SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
如果一个 Channel 要注册到 Selector 中, 那么这个 Channel 必须是非阻塞的, 即channel.configureBlocking(false);
因为 Channel 必须要是非阻塞的, 因此 FileChannel 是不能够使用选择器的, 因为 FileChannel 都是阻塞的.
获取可操作的 Channel

如果 select()方法返回值表示有多个 Channel 准备好了, 那么我们可以通过 Selected key set 访问这个 Channel:

Set<SelectionKey> selectedKeys = selector.selectedKeys();

Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

while(keyIterator.hasNext()) {
    
    SelectionKey key = keyIterator.next();

    if(key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.

    } else if (key.isConnectable()) {
        // a connection was established with a remote server.

    } else if (key.isReadable()) {
        // a channel is ready for reading

    } else if (key.isWritable()) {
        // a channel is ready for writing
    }

    keyIterator.remove();
}

在每次迭代时, 我们都调用 "keyIterator.remove()" 将这个 key 从迭代器中删除, 因为 select() 方法仅仅是简单地将就绪的 IO 操作放到 selectedKeys 集合中, 因此如果我们从 selectedKeys 获取到一个 key, 但是没有将它删除, 那么下一次 select 时, 这个 key 所对应的 IO 事件还在 selectedKeys 中.
例如此时我们收到 OP_ACCEPT 通知, 然后我们进行相关处理, 但是并没有将这个 Key 从 SelectedKeys 中删除, 那么下一次 select() 返回时 我们还可以在 SelectedKeys 中获取到 OP_ACCEPT 的 key.
注意, 我们可以动态更改 SekectedKeys 中的 key 的 interest set. 例如在 OP_ACCEPT 中, 我们可以将 interest set 更新为 OP_READ, 这样 Selector 就会将这个 Channel 的 读 IO 就绪事件包含进来了.

Selector 的基本使用流程

  • 通过 Selector.open() 打开一个 Selector.

  • 将 Channel 注册到 Selector 中, 并设置需要监听的事件(interest set)

  • 不断重复:

    • 调用 select() 方法
    • 调用 selector.selectedKeys() 获取 selected keys
    • 迭代每个 selected key:
      • 从 selected key 中获取 对应的 Channel 和附加信息(如果有的话)

      • 判断是哪些 IO 事件已经就绪了, 然后处理它们. 如果是 OP_ACCEPT 事件, 则调用 "SocketChannel clientChannel = ((ServerSocketChannel) key.channel()).accept()" 获取 SocketChannel, 并将它设置为 非阻塞的, 然后将这个 Channel 注册到 Selector 中.

      • 根据需要更改 selected key 的监听事件.

      • 将已经处理过的 key 从 selected keys 集合中删除.

阿里云Ubuntu部署Steam饥荒联机版服务器:从零到多人联机的完整指南 本文详细介绍了在阿里云Ubuntu系统上部署Steam饥荒联机版服务器的完整流程,包括环境准备、SteamCMD安装、服务端配置、Mod管理及后台运行技巧。通过2核4GB的ECS实例配置和端口设置,实现5人流畅联机体验,适合游戏爱好者快速搭建专属服务器。 阅读详情

相关推荐

[ESP32S3N16R8][LVGL8.3.0][IDF5.2.3]ST7701S RGB屏幕驱动[vscode最详细配置]

ST7701S ESP32S3 基于ESP-IDF5.2.3编写,编程环境为vscode。本教程详细讲述了esp32s3配置st7701s屏幕驱动以及gt911触摸驱动并关联到lvgl8.3.0,使用IDF5.23示例rgb_panel进行测试删除了其里面的屏幕驱动,改为单独编写屏幕和触摸驱动,最后完成了实列。

qq_44022379的博客 2606

java网络编程:NIO

先将Server运行起来 public static void serverStart() throws IOException { //channel bytebuffer selector 三兄弟 ServerSocketChannel channel = ServerSocketChannel.open(); channel.socket()...

waterflying2015的博客 428

Workbuddy+DeepSeek V4傻瓜流配置全指南:API接入、模型切换与Agent实战

AI编程助手的核心价值不在于模型本身,而在于如何稳定、安全、低门槛地调用其能力。Agent作为智能体范式,依赖可靠的运行时环境与标准化API通信;DeepSeek V4系列凭借高吞吐、低延迟和强工具调用支持,成为当前生产级Agent的理想引擎。Workbuddy则通过本地配置管理、环境变量注入与UTF-8无BOM容错等工程设计,将复杂部署简化为可复现、可版本化、可团队协同的实践流程。本文聚焦API接入路径下的真实卡点——从Key获取验证、models.json字段语义到沙箱权限控制,覆盖开发者在Window

weixin_33702545的博客 2370

java nio 捕获异常_java.nio.channels.ClosedSelectorException大概一秒钟抛一次这个异常,怎么破?...

写了一个网关程序,mina框架,POS机发来请求,处理转发请求的,前一段时间日志里发现,程序启动后,不定期的就会开始抛这个异常,但是不影响POS正常使用,大概一秒钟一次,导致日志文件非常大....写了一个网关程序,mina框架,POS机发来请求,处理转发请求的,前一段时间日志里发现,程序启动后,不定期的就会开始抛这个异常,但是不影响POS正常使用,大概一秒钟一次,导致日志文件非常大.应该是mina...

weixin_39781143的博客 1510

STM32H743的ADC还能这么玩?定时器触发+DMA搬运,构建低CPU占用的数据流

本文深入探讨了STM32H743微控制器中ADC的高效使用方法,通过定时器触发和DMA搬运技术实现低CPU占用的数据流采集。详细解析了硬件架构、CubeMX配置步骤及高级优化技巧,包括双缓冲技术和多ADC同步采样,适用于电机控制、音频采集等高性能应用场景。

weixin_30698527的博客 647

YOLO26涨点改进| TGRS 2026 | 独家创新首发、注意力改进篇| 引入CSSCA频谱-空间交叉注意力,含多种创新改进,小目标检测、图像分割、高光谱图像分类、语义分割任务任务涨点

🔥本文提出CSSCA(频谱-空间交叉注意力)模块,通过中心像素引导的光谱与空间交叉注意力机制,有效提升YOLO26模型的特征表达能力。该模块实现了光谱与空间信息的协同优化,能够自适应强化关键通道与重要空间区域,增强模型对小目标和复杂场景的感知能力。文章详细介绍了CSSCA的网络结构、工作原理及四大优势,包括精准特征表达、协同信息优化、小样本适应性和轻量化设计。同时提供了完整的代码实现和四种改进方案的YAML配置文件,包括基础版、增强版、C3k2融合版和C2PSA融合版,为YOLO26模型的性能提升

Ai缝合怪、助力小伙伴高效发论文 267

ClosedSelectorException产生原因及解决方案

通常由于在Selector已经关闭的情况下仍尝试对其进行操作而引发。通过正确管理Selector的生命周期、避免并发访问问题、确保只关闭一次并停止后续操作,可以有效预防此异常的发生。

境里婆娑 1060

基于Simulink的轨道交通信号控制系统仿真详细介绍

轨道交通信号控制系统是确保列车安全、高效运行的核心技术。通过Simulink进行信号控制系统的仿真,可以验证系统的设计、优化调度策略并提高安全性。以下是如何在MATLAB和Simulink中设计并仿真一个轨道交通信号控制系统的详细步骤。通过上述步骤,我们成功设计并实现了基于Simulink的轨道交通信号控制系统仿真。该系统能够根据列车位置、速度和轨道状态生成控制指令,确保列车的安全、高效运行。通过虚拟场景仿真、硬件在环测试和实机测试,验证了系统的性能,并通过参数优化进一步提升了系统的可靠性。引入智能调度。

xiaoheshang_123的博客 462

NIO-Selector类详解

Selector本身为抽象类,AbstractSelector是Selector类的抽象实现类,具体的实现类更加底层(SelectorImpl,位于sun.nio.ch);Selector即为"选择器",支撑了NIO的多路复用.Selector不能直接创建,需要通过Selector.open()获得,该方法将使用系统默认的选择器提供者创建新的选择器(SelectorProvider),可以通过...

深入一点 774

微信小程序 - 最新详细实现跳转打开第三方网站方法流程及示例代码,在小程序内直接打开H5页面或微信公众号文章后台业务域名配置及下载校验文件上传服务器,嵌入外部网站跳转第三方h5网页(详细配置及代码)

微信小程序,打开第三方网站,放校验文件,怎么配置业务域名,后台配置,怎么打开外部没有关联的网站,小程序直接打开公众号文章,指定页面,跳转第三方url,跳转到外部网站,小程序跳转到任意外部网页,网站链接,跳转到其他网页(外部链接),小程序嵌入外部h5链接,校验文件怎么放到对方服务器上,要跳转到网站没权限放过去,校验文件验证域名,把校验文件放到对面网站,别人的服务器也打不开没权限怎么放呢,勾选不校验合法域名,txt,打不开别人的网页怎么办,真机调试打不开,无法跳转,有什么其他办法不放校验文件吗,别人不可能同意,

🏆 前端领域优质创作者 1万+

基于SAHI算法优化YOLOv8的小目标检测性能研究

SAHI(SliceAwareHyperInference)是一种推理优化算法,通过将大图切片为小块并分别推理的方式,实现更精细的小目标检测。提升小目标检测精度:切片后的小目标在每个小块中占比更大,模型能够更好地聚焦。兼容性强:可直接集成到现有目标检测框架中(如YOLO系列、Detectron2等)。支持大分辨率图片和视频推理:减少硬件对大图推理的限制。本文详细探讨了如何通过SAHI(切片辅助超推理算法)结合YOLOv8模型,有效提升小目标检测性能,尤其是在高分辨率图片和视频场景中表现优异。

博客 2371

Selector类的使用(一)

Selector类的使用 Selector类的主要作用是作为SelectableChannel对象的多路复用器。 可通过调用Selector类的open()方法创建选择器,该方法将使用系统的默认SelectorProvider创建新的选择器。也可通过调用自定义选择器提供者的openSelector()方法来创建选择器。在通过选择器的close()方法关闭选择器之前,选择器一直保持打开状态。 通过SelectionKey对象来表示SelectableChannel (可选择通道)到选择器的注册。选择器维护了

吴声子夜歌的博客 1641

TC8:IPv4_HEADER_01-04

IPv4_HEADER_01: Ensure that the DUT generates an IPv4 Packet with a Total Length greater than or equal to 20 目的 确保DUT生成的IPv4报文的IP头部中的Total Length字段值大于等于20 IPv4协议头部中的Total Length字段表示整个IP数据包的长度,包括IP Header和payload之和,IP首部的长度最少就有20个字节,所以Total Length值肯定大于等于20

jasonj333 3961

API笔记之java.nio.channels.SelectionKey

API笔记之java.nio.channels.SelectionKey   Java代码  import java.nio.channels.SelectableChannel;   import java.nio.channels.Selector;   import java.util.concurrent.atomic.AtomicReferenceFie

莫名的拉风的博客 2141

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

SelectableChannel API 用法

java.nio.channels 类 SelectableChannel java.lang.Object java.nio.channels.spi.AbstractInterruptibleChannel java.nio.channels.SelectableChannel 所有已实现的接口: Closeable, Channel, InterruptibleCha

大树叶 技术专栏 1412

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

java nio

服务器在合理的时间之内处理大量客户机请求的能力取决于服务器使用 I/O 流的效率。同时为成百上千个客户机提供服务的服务器必须能够并发地使用 I/O 服务。Java 平台直到 JDK 1.4(也就是 Merlin)才支持非阻塞 I/O 调用。用 Java 语言写的服务器,由于其线程与客户机之比几乎是一比一,因而易于受到大量线程开销的影响,其结果是既导致了性能问题又缺乏可伸缩性。 为了解决这...

虚客 180

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

java nio的学习-9

继续----------------》》》》》》》》》》》 使用选择器----------->>>>>>>>>>>> 选择过程 :在详细了解 API 之前,您需要知道一点和 Selector 内部工作原理相关的知识。就像上面探讨的那样,选择器维护着注册过的通道的集合,并且这些注册关系中的任意一个都是封装在SelectionKey对象中的。每一个 Selector 对象维护三个键

geli_hero的专栏 1213

Java网络服务器编程(NIO版)

    Java网络服务器编程 一文演示了如何使用Java的Socket API编写一个简单的TCP Echo Server。其阻塞式IO的处理方式虽然简单,但每个客户端都需要一个单独的Thread来处理,当服务器需要同时处理大量客户端时,这种做法不再可行。使用NIO API可以让一个或有限的几个Thread同时处理连接到服务器上的所有客户端。(关于NIO API的一些介绍,可以在Jav...

iteye_8559的博客 180

Selector API用法

java.nio.channels 类 Selector java.lang.Object java.nio.channels.Selector 直接已知子类:AbstractSelector public abstract class Selectorextends Object SelectableChannel 对象的多路复用器。 可通过调用此类的 open 方法创建选择器,该方法...

weixin_33904756的博客 106

引进nio的目的

之前的 I/O 编程 在 JDK 1.4 之前,自由地使用线程是处理阻塞问题最典型的办法。但这个解决办法会产生它自己的问题 ― 即线程开销,线程开销同时影响性能和可伸缩性。 用 Java 语言写的服务器,由于其线程与客户机之比几乎是一比一,因而易于受到大量线程开销的影响,其结果是既导致了性能问题又缺乏可伸缩性。 为了解决这个问题,Java 平台引入了一组新的类。java.nio

jmxyandy的专栏 1571

Java的selectionkey_SelectionKey API 用法

java.nio.channels类 SelectionKeyjava.lang.Objectjava.nio.channels.SelectionKey直接已知子类:AbstractSelectionKeypublic abstract class SelectionKeyextends Object表示 SelectableChannel 在 Selector 中的注册的标记。每次向选择器注册...

weixin_34116482的博客 458

merlin jffs_Merlin为Java平台带来了非阻塞I / O

服务器在合理的时间内处理大量客户端请求的能力取决于服务器使用I / O流的效率。 同时满足数百个客户端的服务器必须能够同时使用I / O服务。 在JDK 1.4(又名Merlin)之前,Java平台不支持非阻塞I / O调用。 由于线程与客户端的比例几乎为一比一,因此用Java语言编写的服务器容易受到巨大的线程开销,从而导致性能问题和可伸缩性不足。 为了解决此问题,最新版本的Java平台引...

cusi77914的博客 274

4.JAVA NIO选择器

第四章 选择器 选择器提供选择执行已经就绪的任务的能力,这使得 多元 I/O 成为可能。就像在第一章中描述的那样,就绪选择和多元执行使得单线程能够有效率地同 时管理多个 I/O 通道(channels)。C/C++代码的工具箱中,许多年前就已经有 select()和 poll()这两个 POSIX(可移植性操作系统接口)系统调用可供使用了。 许过操作系统也提供相似的功能,但对 Java 程序员来...

kakarot5的专栏 470

java中io与nio的使用

地址 http://www.ibm.com/developerworks/cn/java/j-javaio/ 2002 年 3 月 12 日 Java 技术平台早就应该提供非阻塞 I/O 机制了。幸运的是,Merlin(JDK 1.4)有一根几乎在各个场合都适用的魔杖,而解除阻塞了的 I/O 的阻塞状态正是这位魔术师的专长。软件工程师 Aruna Kalagn...

weixin_30848775的博客 58
上一篇: Java NIO之ServerSocketChannel类
下一篇: Java NIO之SelectionKey类
Coder_py
博客等级 码龄10年 106粉丝 258原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值