Java NIO高并发核心是Reactor模型:单线程用Selector监控千级连接,事件就绪才处理;关键三步为通道非阻塞、select轮询、事件分发;须用DirectBuffer并正确flip/clear;业务逻辑须移交线程池;生产环境推荐主从Reactor架构。

Java NIO 高并发编程实战,核心不是堆代码,而是建模型:用一个线程(或少量线程)通过 Selector 监控成百上千个连接,只在数据真正就绪时才处理——避免线程空等、减少切换、压低资源消耗。
关键三步:通道非阻塞 + 选择器轮询 + 事件分发
这是 NIO 服务端最简但完整的骨架,也是所有高并发实现的起点:
- ServerSocketChannel 设为非阻塞,并注册 OP_ACCEPT 到 Selector
- 调用 selector.select() 阻塞等待就绪事件(可设超时)
- 遍历 selectedKeys(),按事件类型分发:
– 是 OP_ACCEPT:接收新连接,将其 SocketChannel 设为非阻塞,注册 OP_READ
– 是 OP_READ:从 channel 读取数据到 ByteBuffer,解析后响应或转发
– 是 OP_WRITE:仅在写缓冲区满、需继续发送时才注册,用完立即取消,避免忙轮询
必须用 DirectBuffer + flip/clear 控制读写状态
HeapBuffer 每次 IO 都要拷贝到内核态,高并发下是性能黑洞。直接用 ByteBuffer.allocateDirect(8192);每次读完调 buffer.flip() 切换为读模式,读完再 buffer.clear() 复位,否则 position/limit 错乱导致丢数据或死循环。
别让业务逻辑卡住事件循环线程
Reactor 线程只做 I/O 调度,不能执行耗时操作(如数据库查询、JSON 解析、复杂计算)。常见做法:
– 读到完整请求后,封装成任务提交到业务线程池(如 ForkJoinPool.commonPool() 或自定义 ThreadPoolExecutor)
– 写响应时,若 channel.write() 返回值小于待写字节数,说明 TCP 缓冲区已满,需注册 OP_WRITE 并把剩余 buffer 持有住,等下次就绪再续写
– 所有 ChannelHandler 必须无状态、线程安全,避免共享可变对象
立即学习“Java免费学习笔记(深入)”;
生产级建议:主从 Reactor + 连接管理
单 Reactor 在万级连接+高频读写时容易成为瓶颈。进阶结构:
– 主 Reactor 线程只负责 accept,把新连接的 SocketChannel 轮询分配给多个从 Reactor 线程
– 每个从 Reactor 独立持有 Selector,负责对应连接的 read/write
– 用 ConcurrentMap
– 客户端断连时,务必在 cancelled 回调中 clean up:关闭 channel、移除 key、释放 buffer 引用,防止内存泄漏



















