V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
atfeel
V2EX  ›  Android

NIO 的疑惑,多线程下调用 register 阻塞,是什么原因呢?

  •  
  •   atfeel · 2022-08-28 10:07:50 +08:00 · 4450 次点击
    这是一个创建于 608 天前的主题,其中的信息可能已经有所发展或是发生改变。

    1 、在主线程统一轮询处理 select() 2 、子线程调用 register 注册通道。

    register 会阻塞,无法往下执行。什么原因造成的呢?又该如何避免呢?各位有没有碰到过呢

    5 条回复    2022-08-29 10:45:16 +08:00
    dreamlike
        1
    dreamlike  
       2022-08-28 18:50:23 +08:00 via Android
    有这个问题说明你应该是 j8 左右的版本,这个是内部实现问题 select 会持有和 register 相同的一把锁 具体请看
    https://bugs.openjdk.org/browse/JDK-6446653
    11 改了一次实现 就不会了
    但是还是推荐 register 和 select 在同一个线程中执行,比如说先投递到 select 对应的线程队列中一个 register 任务 再调用 wakeup 让它从 select 中返回
    atfeel
        2
    atfeel  
    OP
       2022-08-28 20:47:00 +08:00
    @dreamlike 大佬,你说 j8 是 java8 吗?还是 jdk8 呢?
    atfeel
        3
    atfeel  
    OP
       2022-08-28 21:07:32 +08:00
    @dreamlike 我也想把轮询和注册写在同一线程,但是注册完以后轮询是写在 while 里的,如果不写在新的线程里,那就是整个线程都堵塞在 select ,就没办法做其他操作了。
    dreamlike
        4
    dreamlike  
       2022-08-28 22:04:58 +08:00 via Android   ❤️ 1
    atfeel
        5
    atfeel  
    OP
       2022-08-29 10:45:16 +08:00
    @dreamlike 太牛了,昨天我也式了唤醒再注册这种方式,测试结果是,网络请求比直接同步请求多了 20ms,想不到这个 class 这么全面,大佬果然牛!!!仰望感谢
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1201 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 23:36 · PVG 07:36 · LAX 16:36 · JFK 19:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.