Java NIO笔记(八):选择器

STM32G4实战:用CubeMX+Keil五分钟搞定FreeRTOS多任务LED控制(避坑指南) 本文详细介绍了如何在STM32G4系列芯片上使用CubeMX和Keil快速配置FreeRTOS实现多任务LED控制,包括环境准备、时钟配置、任务创建及常见问题解决方案。重点解决了时钟源冲突等高频问题,并提供了优化建议和进阶应用示例,帮助开发者高效完成嵌入式开发任务。 阅读详情

        NIO中的选择器(Selector)的作用就是维护注册到选择器中的通道集合,每一个通道与选择器的关系封装在选择键(SelectionKey)中,实际上可以认为选择器维护的是选择键集合。创建Selector对象使用Selector.open()。

        Selector类主要维护三个集合:

  • Registered key set(已注册键集合):调用Selector的keys()方法可以获取
  • Selected key set(已选择键集合):调用Selector的selectedKeys()方法获取
  • Cancelled key set(已取消键集合):已取消键集合是Selector对象的私有成员,外部无法访问

        只有继承了SelectableChannel的类才能注册到选择器中,并且只有非阻塞模式的通道才能注册到选择器,如下代码:

		//创建一个套接字服务器,并注册到选择器
		//创建选择器
		Selector selector = Selector.open();
		//创建Socket服务器通道
		ServerSocketChannel ssc = ServerSocketChannel.open();
		//绑定65535端口
		ssc.socket().bind(new InetSocketAddress(65535));
		//设置通道为非阻塞模式
		ssc.configureBlocking(false);
		//将通道注册到选择器,指定通道兴趣是等待接收连接
		SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);

        实际使用中,一般使用while循环轮询获取注册到选择器中通道感兴趣的操作,如下代码:

		while (true) {
			int n = selector.select();
			if (n > 0) {
				Iterator<SelectionKey> iter = selector.selectedKeys().iterator();
				while (iter.hasNext()) {
					SelectionKey keyy = iter.next();
					iter.remove();
					// ......
				}
			}
		}
        select()方法的作用是选择注册到选择器中通道感兴趣的键,此方法是阻塞的,直到有感兴趣的事件发生;还可以使用select(10000)方法设置选择键的超时时间,单位是Millisecond;还可以使用selectNow(),此方法是非阻塞,若没有通道就绪会立即返回0。

        不需要使用Selector时,调用close()方法可以关闭选择器,关闭选择器后,所有注册到其中的选择键会被设置为无效状态。

        关闭选择器后,试图调用它的方法会抛出ClosedSelectorException,这是一个非运行时异常,所有在使用时有必要检查选择器是否打开,使用isOpen()方法。

        NIO中定义了4中可选择操作:OP_READ(读)、OP_WRITE(写)、OP_CONNECT(连接)、OP_ACCEPT(接受),这些常量在SelectionKey中定义。可以使用通道的validOps()获取某个通道上支持的操作集合。

        同一个通道可以被多次注册到同一个选择器中,没有异常错误,也没有特别的效果,个人觉得这个地方设计的不严谨;实际使用中应避免同一个通道多次注册到一个选择器中,虽然对实际功能没有影响,但是为了整体思路清晰最好不要这么做。

        注册一个通道时可以在这个选择键上设置一个Object对象,比如在接受连接操作中设置,在读操作中获取,如下代码:

					SelectionKey keyy = iter.next();
					iter.remove();
					if(keyy.isAcceptable()){
						ServerSocketChannel channel = (ServerSocketChannel) keyy.channel();
						SocketChannel sc = channel.accept();
						sc.register(selector, SelectionKey.OP_READ, "hello");
					}
					if(keyy.isReadable()){
						//attach的值为"hello"
						Object attach = keyy.attachment();
						SocketChannel sc = (SocketChannel) keyy.channel();
					}
        SelectionKey(选择键对象)提供了下面方法:
  • channel():获取关联的通道(SelectableChannel)
  • selector():获取关联的选择器(Selector)
  • isValid():验证维护选择器与通道关系的SelectionKey是否有效
  • cancel():取消键,调用一个已取消的键的方法将抛出CancelledKeyException
  • interestOps():获取这个key的兴趣(可选择操作)集合
  • interestOps(int ops):设置这个key的兴趣
  • readyOps():返回这个key准备好的操作集合(兴趣集合)
  • isReadable():检查选择键的兴趣是否为可读,实际上是通道的兴趣,选择键维护通道与选择器关系
  • isWritable():检查选择键的兴趣是否为可写
  • isConnectable():检查选择键的兴趣是否为连接
  • isAcceptable():检查选择键的兴趣是否为接受
  • attach(Object ob):设置一个Object数据到此key上
  • attachment():获取设置的Object数据

        可以设置null来清楚SelectionKey的附件对象,如果SelectionKey的存在周期很长,但是附件对象不需要存在很长,一定要再使用完后即时清理附件对象,否则附件对象不能被GC回收,可能会发生内存泄露。

        停止选择过程可以使用Selector的wakeup()方法,此方法可以安全的退出select()阻塞,

        选择器对象(Selector)是线程安全的,在多线程并发访问不会有问题。

        Selector(选择器)提供了下面方法:

  • open():打开一个选择器
  • isOpen():检查一个选择器实例是否打开
  • provider():返回一个SelectorProvider
  • keys():返回注册键集合
  • selectedKeys():返回已选择键集合
  • selectNow():立刻执行选择,非阻塞,若没有已准备好的通道则立即返回0
  • select(long timeout):执行选择,超过指定毫秒数则返回
  • select():执行选择,会一直阻塞直到有准备就绪的通道
  • wakeup():停止选择
  • close():关闭选择器

        使用Selector类可能会抛出的错误:

  • IllegalBlockingModeException:注册一个阻塞状态的通道抛出此异常
  • ClosedChannelException:注册一个已关闭的通道抛出此异常
  • ClosedSelectorException:调用一个已关闭的选择器的方法抛出此异常
  • UnsupportedOperationException:已注册的键集合是只读,修改它会抛出此异常
模拟量输入功能块 S_ITR(Easy系列PLC完整ST源代码) IN Input INT 输入数字量 1IN ISH INT 输入数字量上限 2IN ISL INT 输入数字量下限 3IN OSH REAL 输出工程量上限 4IN OSL REAL 输出工程量下限 5OUT OUTPUT REAL 输出工程量 6VAR temp1 REAL 临时变量1 7VAR temp2 REAL 临时变量2 8。 阅读详情

相关推荐

WSL2+Ubuntu20.04纯root环境搭建指南:告别权限烦恼的终极方案

本文提供了一份详细的WSL2+Ubuntu20.04纯root环境搭建指南,旨在为本地开发与学习打造一个免去权限干扰、极致流畅的Linux子系统环境。通过启用WSL2、安装Ubuntu 20.04,并执行核心的root用户设置,开发者可以彻底告别频繁的sudo操作,提升在文件操作、容器调试和系统配置等方面的效率。

time3的博客 474

java网络编程:NIO

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

waterflying2015的博客 428

基于CLICKHOUSE的数据仓库分层规范

接入层。

zjyy1987的博客 770

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

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

weixin_39781143的博客 1510

亿图图示(edrawmax中文版) v10.1.7pjb

edrawmax中文名叫做亿图图示,是一款非常棒的综合图形图表设计软件,既能实现流程图、架构图、工程图、思维导图等数百种专业领域图形图表的绘制,又能提供一个白板进行头脑风暴和任意编排,轻松实现数据和创意的可视化呈现。软件支持Windows、Mac、Linux及网络版,一端创作,多端同步,从而为跨端办公绘图提供新的解决方案,还兼容常用文档类的办公软件格式,包括图片、Office、PDF、Visio、Html、SVG等,尽可能的在文件格式这块满足用户多方面需求。软件支持创建260多种图表类型,拥有超过12500

qq_43293214的博客 1万+

DP_AUX辅助通道介绍

DisplayPort(简称DP)是一个由PC及芯片制造商联盟开发,视频电子标准协会(VESA)标准化的数字式视频接口标准。其中辅助通道(AUX)是一条独立双向半双工的传输通道,它也是一对差分信号线。其数据传输速率1Mbps,用来传输配置参数与指令。

cjie221的博客 5356

ClosedSelectorException产生原因及解决方案

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

境里婆娑 1060

Hermes-Agent-完整指南

Hermes Agent 是由 **Nous Research** 开发的一款**自我改进型 AI Agent**,具有内置的学习闭环系统。它的核心理念是"一个与你共同成长的 Agent"。- 能够从经验中创建技能(Skill-Learning Automated),在使用过程中自我改进, 跨会话持久记忆, 深度用户建模

liu_zhiyi的博客 3037

NIO总结(三) NIO之Selector

引言: 之前我们使用BIO进行socket编程时,accept方法会一直阻塞,直到有客户端请求的到来,并返回socket进行相应的处理。整个过程是流水线的,处理完一个请求,才能去获取并处理后面的请求,当然也可以把获取socket和处理socket的过程分开,一个线程负责accept,一个线程池负责处理请求。 但NIO提供了更好的解决方案,采用选择器(Selector)返回已经准备好的socket,...

盐二白 557

检测头篇 | 手把手教你如何去更换YOLOv8的检测头为ASFF_Detect

自适应空间特征融合(ASFF)的主要原理旨在解决单次检测器中不同尺度特征的不一致性问题。具体来说,ASFF通过动态调整来自不同尺度特征金字塔层的特征贡献,确保每个检测对象的特征表示是一致且最优的。本文所做出的改进是将YOLOv8的检测头更换为ASFF_Detect。🌈

小哥谈 2499

Python 爬虫实战:全面解析雪球网用户投资组合数据采集

本文介绍了如何使用 Python 爬虫技术,抓取雪球网用户的投资组合信息。通过模拟登录、解析页面内容等步骤,获取了用户的持仓数据。未来,可以进一步探索以下方向:

2201_76125261的博客 1304

Java NIO Selector选择器

Selector是Java NIO中的一个关键组件,用于单线程管理多个网络通道(Channel),检查它们是否处于可读、可写等状态。通过使用Selector,可以减少线程数量,降低系统资源消耗,因为线程切换在操作系统中是开销较大的操作。Selector通过Selector.open()创建,并通过register()方法将非阻塞的Channel注册到Selector上,监听连接、接收、读、写等事件。Selector的select()方法用于检测就绪的Channel,返回就绪的Channel数量,并通过sel

Java的专栏 1054

高通 vs MTK vs 海思:三大平台 ISP 架构横向对比与实战差异分析

随着移动影像能力成为智能终端差异化竞争的核心维度,ISP(Image Signal Processor)架构日益重要。高通、MTK、海思三大 SoC 厂商在 ISP 设计上各具特色,不仅在图像处理链路、模块集成度、算法加速路径等方面存在显著差异,同时也决定了终端厂商在成像质量、调试复杂度与扩展能力上的实际表现。本文将基于真实平台项目经验,横向对比三大主流平台的 ISP 架构关键指标,系统分析其在实际开发过程中的能力边界、工程成本与调优空间,帮助工程师更精准地进行平台选型与优化策略制定。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 3933

Java NIO系列4:通道和选择器

前言今天加班回来,终于有时间继续更新NIO的文章了。在前一篇文章我们讲解了缓冲区的知识,并通过代码演示了如何使用缓冲区的API完成一些操作。这里要讲的通道于缓冲区关系密切,简单来说,缓冲区是填充数据的载体,而通道则可以理解为传输数据的载体。回忆在TCP/IP中建立握手的过程,发送端有一个发送缓冲区而接受端有一个接收缓冲区,进程从缓冲区中取数据,之后缓冲区又可以被填满,而传输数据的网络则可以理解为通道

rhwayfun专栏 1万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java NIO选择器

在Java NIO中,选择器(Selector)是可选择通道的多路复用器,可用作可以进入非阻塞模式的特殊类型的通道。它可以检查一个或多个NIO通道,并确定哪个通道准备好了可以进行通信,即读取或写入。

unber的博客 554

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java Nio选择器Selector

Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接 ,减少服务器的性能开销。创建Selector通过Selector 提供的静态方法创建    Selector selector = Selector.open();通过SelectorProvider获取选择...

白开水_Arvin的博客 327

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Java NIO之选择器

1.简介 前面的文章说了缓冲区,说了通道,本文就来说说 NIO 中另一个重要的实现,即选择器 Selector。在更早的文章中,我简述了几种 IO 模型。如果大家看过之前的文章,并动手写过代码的话。再看 Java 的选择器大概就会知道它是什么了,以及怎么用了。选择器是 Java 多路复用模型的一个实现,可以同时监控多个非阻塞套接字通道。示意图大致如下: 如果大家了解过多路复用模型,那应...

dishitu6229的博客 396

java的选择器_【NIO】Java NIO之选择器

一、前言前面已经学习了缓冲和通道,接着学习选择器。二、选择器2.1 选择器基础选择器管理一个被注册的通道集合的信息和它们的就绪状态,通道和选择器一起被注册,并且选择器可更新通道的就绪状态,也可将被唤醒的线程挂起,直到有通道就绪。SelectableChannel 可被注册到 Selector 对象上,同时可以指定对那个选择器而言,哪种操作是感兴趣的。一个通道可以被注册到多个选择器上,但对每个选择器...

weixin_39725844的博客 286

java nio attachment_Java NIO:选择器

最近打算把Java网络编程相关的知识深入一下(IO、NIO、Socket编程、Netty)Java NIO主要需要理解缓冲区、通道、选择器三个核心概念,作为对Java I/O的补充, 以提升大批量数据传输的效率。学习NIO之前最好能有基础的网络编程知识传统监控多个Socket的Java解决方案是为每一个Socket创建一个线程并使线程阻塞在read调用处, 直到数据可读。这种方式在系统并发不高时可...

weixin_39637151的博客 130

JAVA NIO:NIO与OIO的对比以及Channel通道、Selector选择器、Buffer缓冲区的介绍 //高并发

文章目录二 Java NIO(一)NIO对比OIO(二)概述三个核心组件Channel通道Selector选择器Buffer缓冲区(三)Buffer详解1 Buffer类2 四个属性3 重要方法(四)Channel详解1 FileChannel文件通道2 SocketChannel套接字通道3 DatagramChannel数据报通道(五)Selector选择器选择器使用流程:1、获取选择器示例2.将通道注册到选择器四种IO事件类型:SelectableChannel可选择通道validOps()Selec

蛙爸爸的博客 1269

NIO Selector选择器解析

通过select系列方法,选择器会通过JNI,去进行底层操作系统的系统调用(比如select/epoll),可以不断地查询通道中所发生操作的就绪状态(或者IO事件),并且把这些发生了底层IO事件,转换成Java NIO中的IO事件,记录在的通道关联的SelectionKey的readyOps上。在事件处理过程中,对于新建立的socketChannel客户端传输通道,也要注册到同一个选择器上,这样就能使用同一个选择线程,不断地对所有的注册通道进行选择键的查询。并不是所有的通道,都是可以被选择器监控或选择的。

ntzzzsj的博客 1421

java标签选择器,Java NIO:选择器

最近打算把Java网络编程相关的知识深入一下(IO、NIO、Socket编程、Netty)Java NIO主要需要理解缓冲区、通道、选择器三个核心概念,作为对Java I/O的补充, 以提升大批量数据传输的效率。传统监控多个Socket的Java解决方案是为每一个Socket创建一个线程并使线程阻塞在read调用处, 直到数据可读。这种方式在系统并发不高时可以正常运行,如果是并发很高的系统就需要创...

weixin_39914732的博客 97

java nio nio2 区别_Java NIO2:NIO概述

一、概述从JDK1.4开始,Java提供了一系列改进的输入/输出处理的新特性,被统称为NIO(即New I/O)。新增了许多用于处理输入输出的类,这些类都被放在java.nio包及子包下,并且对原java.io包中的很多类进行改写,新增了满足NIO的功能。NIO采用内存映射文件的方式来处理输入输出,NIO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样访问文件了。NIO 与原来的 I/...

weixin_28695161的博客 1124

JAVA NIO:NIO与OIO的对比以及Channel通道、Selector选择器、Buffer缓冲区的介绍 高并发

文章目录 二 Java NIO (一)NIO对比OIO (二)概述三个核心组件 Channel通道 Selector选择器 Buffer缓冲区 (三)Buffer详解 1 Buffer类 2 四个属性 3 重要方法 (四)Channel详解 1 FileChannel文件通道 2 SocketChannel套接字通道 3 DatagramChannel数据报通道 (五)Selector选择器 选择器使用流程: 1、获取选择器示例 2.将通道注册到选择器 四种IO事件

m0_67401153的博客 560

Java NIO之Selector(选择器)

**Java高级特性增强-NIO 本部分网络上有大量的资源可以参考,在这里做了部分整理并做了部分勘误,感谢前辈的付出,每节文章末尾有引用列表~ 写在所有文字的前面:作者在此特别推荐Google排名第一的关于NIO的文章: http://tutorials.jenkov.com/java-nio/index.html 虽然是英文的,但是看下来并不困难。后面如果各位看官呼声很高,作者会翻译这一系列文...

微信搜:import_bigdata,大数据领域硬核原创作者 343
上一篇: Java NIO笔记(七):Socket通道
下一篇: 关于使用nio实现广播数据给所有已连接客户端
xlight2023
博客等级 码龄15年 236粉丝 32原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值