nio当数据来了,是由哪个线程读取的

10次阅读
没有评论

背景

 

多路复用:线程调用 selector.select()。这个方法会询问内核:我管辖的这一千个 Channel 里,谁的数据准备好了?内核告诉它:“C 和 D 准备好了”。 那么这个数据准备好了,还是这个线程去读取吗?

 

这是一个非常核心的问题。简单直接的回答是:是的,在标准的 Java NIO 编程模型中,依然是由这个线程(Selector 所在的线程)去执行实际的 read() 操作。

但这里有一个非常关键的**“误区”**需要澄清:数据“准备好了”到底是指什么?


1. 数据的两个阶段(以读为例)

在 Linux 内核层面,一个输入操作通常包含两个阶段:

  1. 等待数据准备好(数据到达网卡,并拷贝到内核缓冲区)。

  2. 将数据从内核拷贝到用户进程(从内核缓冲区拷贝到 JVM 的 ByteBuffer 中)。

Selector 线程在做什么?

  • selector.select():这个过程是在等阶段 1。线程在这里可能是阻塞的,但它是一次性等一千个 Channel。

  • channel.read(buffer):当 Selector 发现 C 和 D 就绪了,这个线程会退出阻塞,去调用 read()这个 read() 过程执行的是阶段 2(拷贝数据)。


2. 为什么还是这个线程读?(同步 vs 异步)

这里涉及到一个容易混淆的概念:NIO 是“同步非阻塞” IO。

  • 同步(Synchronous):意味着“内核拷贝数据到用户空间”这个动作,必须由用户线程自己来完成。

  • 非阻塞(Non-blocking):意味着如果没有数据,read() 立即返回,不卡在那里。

所以,虽然 Selector 帮你监控了成千上万个连接,但一旦发现有肉(数据)到了,Selector 线程还是得亲自伸筷子去夹(执行 read() 拷贝数据)


3. 性能瓶颈:如果 C 和 D 的数据很大怎么办?

这就是为什么在实际开发(如 Netty 框架)中,我们不会只用一个线程干所有的活。

如果 Selector 线程在读 C 的数据时花了太长时间,那么 D、E、F 的请求就会被延时。为了解决这个问题,通常会采用 Reactor 模式

  1. MainReactor(老板):一个线程专门负责 accept 新连接。

  2. SubReactor(经理):少量几个线程(通常是 CPU 核数的 2 倍)负责 selector.select()read() 数据

  3. Worker Thread Pool(工人):一旦 read() 完数据,立即丢给业务线程池去处理复杂的逻辑(比如查数据库、算公式)。


4. 真正不需要线程去读的:AIO (Proactor)

如果你希望“数据准备好,且内核自动帮我考贝到内存里,再通知我直接用”,那是 AIO(Asynchronous IO,异步 IO)

  • NIO:内核说“菜洗好了,你自己来炒”。(同步)

  • AIO:内核说“菜炒好了,就在桌子上,你直接吃”。(异步)

冷知识:虽然 Java 支持 AIO,但在 Linux 平台上,AIO 的底层实现并不如 NIO 成熟,所以目前像 Netty 这样的主流框架,核心依然是基于 NIO 的多路复用 模式。


总结

在你的描述中,这个线程就像一个巡逻员。他发现 C 和 D 有情况(数据就绪),他会亲自过去把数据搬(read)出来。搬完之后,他可能会自己处理,也可能会喊一帮“搬运工”(业务线程池)来处理,而他自己继续回去巡逻。

你想看看 Netty 是如何通过 BossGroupWorkerGroup 来完美分配这些线程工作的吗?

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-03-13发表,共计1367字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)

摆渡资源站

文章搜索
一言一句话
-「
热门文章
某个货币持仓增长了一倍,但是 jing流入没有增加多少,为啥

某个货币持仓增长了一倍,但是 jing流入没有增加多少,为啥

  这通常是因为该货币的市值(价格)上涨抵消了持仓量的增加,或者存在某些“非交易性”的变动。 简单来...
2026比特币稳赚指南:顶级加密交易策略全揭秘!

2026比特币稳赚指南:顶级加密交易策略全揭秘!

    关键要点 定投(DCA):仍是比特币长期积累的低风险和纪律性策略。 趋势交易和波段...
使用Java类库ta4j计算基金的布林轨

使用Java类库ta4j计算基金的布林轨

ta4j简介 对于做金融分析的从业者而言,python的ta-lib是不可或缺的技术分析库,具有简单易用、功能...
全真早晚功课简介

全真早晚功课简介

         道教的斋醮仪式很多,主要的日常宗教活动是早晚功课经。凡是道教徒每天都要上殿唪诵,所...
吕祖朝科

吕祖朝科

  举步朝金阙    飞身谒玉京  天外琳琅响    齐举步虚声   步虚  宝座临金殿    霞光...
最新评论
333985 333985 每天都在战争,希望2026和平.
最新文章
普通异步、守护定时和关键定时 线程池

普通异步、守护定时和关键定时 线程池

  这段配置通过区分普通异步、守护定时和关键定时三种模式,很好地覆盖了后端开发中的典型并发场景。 以...
同步和非阻塞关系

同步和非阻塞关系

背景 同步(Synchronous):意味着“内核拷贝数据到用户空间”这个动作,必须由用户线程自己来完成。 非...
nio当数据来了,是由哪个线程读取的

nio当数据来了,是由哪个线程读取的

背景   多路复用:线程调用 selector.select()。这个方法会询问内核:我管辖的这一千...
nio的线程是什么?

nio的线程是什么?

背景 IO 的各种流是阻塞的。这意味着,当一个线程调用 read() 或 write()时,该线程被阻塞,直到...
女生的生理期和非生理期的对于男生的态度差别好大,连性兴趣都变了

女生的生理期和非生理期的对于男生的态度差别好大,连性兴趣都变了

  这是一个非常普遍且具有生物学依据的观察。女生的这种“判若两人”,其实背后有一套非常精密的激素驱动...