Java 中 NIO 的 Selector 唤醒机制怎么通过 wakeup 实现

阿宇酱_4156

阿宇酱_4156

2026-09-06

319人浏览

原创

java nio的selector唤醒机制核心是wakeup()方法,它中断阻塞在select()上的线程使其立即返回0,而非通知继续执行;适用于新channel注册、interestops修改及外部指令驱动等场景,且多次调用不累积,线程安全但需手动处理假唤醒。

java 中 nio 的 selector 唤醒机制怎么通过 wakeup 实现

Java NIO 的 Selector 唤醒机制核心就是 wakeup() 方法,它不是“通知线程继续执行”,而是**中断当前阻塞在 select() 上的线程**,让其立即从阻塞中返回,以便及时响应新注册的 Channel、已就绪的 I/O 事件或外部控制逻辑。

唤醒的本质是中断阻塞调用

Selector 的 select()、select(long timeout) 和 selectNow() 行为不同:
– selectNow() 非阻塞,立刻返回;
– select() 和带超时的 select(long) 会阻塞,直到有 Channel 就绪、超时,或被显式唤醒。
而 wakeup() 的作用,就是在任意线程中调用它,使正在阻塞的 select() 调用**立即返回 0(表示本次未轮询到就绪 Channel)**,且不会抛异常——它通过底层操作系统级别的机制(如向内部管道写入一个字节)触发阻塞系统调用返回。

wakeup() 的典型使用场景

它常用于多线程协作中,让 I/O 线程及时感知到主线程或其他工作线程的变更请求:

Alibabacloud Sdk Client Initialization For Java
Alibabacloud Sdk Client Initialization For Java

在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。

下载
  • 注册新 Channel:当其他线程调用 selector.register(...) 时,若 selector 正在 select 阻塞中,需先 wakeup(),否则新注册可能延迟到下次 select 才生效;
  • 取消 Channel 或修改 interestOps:比如关闭连接后调用 selectionKey.cancel(),虽然 cancel 是线程安全的,但若 selector 正阻塞,取消效果要等下一次 select 才被清理,wakeup 可加速清理流程;
  • 外部指令驱动:如收到 shutdown 信号、配置重载、心跳检测失败等,需让 selector 立即退出阻塞,进入清理或状态切换逻辑。

注意 wakeup() 的几个关键细节

它看似简单,但容易误用:

  • 多次 wakeup() 不会累积:连续调用多次 wakeup(),只保证下一次 select() 被唤醒一次;如果 selector 当前未阻塞,wakeup() 会“预置唤醒状态”,下次调用 select() 会立即返回(相当于一次“待生效”的唤醒);
  • 唤醒后需手动处理“假唤醒”:select 返回后,必须检查 selectedKeys() 是否为空,并重新调用 select()(或带超时的版本),否则可能陷入空转循环;
  • 线程安全,但无需同步调用:wakeup() 是线程安全方法,可由任意线程随时调用,不需要加锁或与 selector 所在线程同步;
  • 不能替代事件通知逻辑:wakeup 只是“打断阻塞”,不是“传递数据”。真正的新连接、读写事件仍需通过 selectedKeys() 遍历获取,不能靠 wakeup 来判断发生了什么。

一个最小可运行示例片段

假设有一个单线程 Selector 循环:

Thread ioThread = new Thread(() -> {
    try {
        while (!shutdown) {
            int n = selector.select(); // 阻塞等待
            if (n == 0) continue;      // 被 wakeup 或超时,无就绪事件

            Iterator<selectionkey> iter = selector.selectedKeys().iterator();
            while (iter.hasNext()) {
                SelectionKey key = iter.next();
                iter.remove();
                if (key.isAcceptable()) handleAccept(key);
                else if (key.isReadable()) handleRead(key);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
});
ioThread.start();

// 其他线程中:要注册新 Channel
SocketChannel ch = SocketChannel.open();
ch.configureBlocking(false);
ch.register(selector, SelectionKey.OP_READ); // 注册后立即 wakeup
selector.wakeup(); // 确保 select 不会卡住,新 channel 下次能被处理
</selectionkey>

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

java

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

9077

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

6262

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

5612

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1004

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

848

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1176

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2389

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19731

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1095

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习