三大组件
Channel
1、Channel 表示打开到 IO 设备(如:文件、套接字)的连接
2、Channel 类似于 Stream
(1)Stream 为单向通道:输入 / 输出
(2)Channel 为读写数据的双向通道,可以从 Channel 将数据读取 Buffer,可以将数据写入 Buffer
(3)Channel 比 Stream 更底层
(4)可以异步地读写
(5)通道中的数据总是要先读到一个 Buffer,或者总是要从一个 Buffer 中写入
3、常见
(1)FileChannel:读写文件数据
(2)DatagramChannel:UDP 网络通信
(3)SocketChannel:TCP 网络通信,客户端、服务端都能用
(4)ServerSocketChannel:TCP 网络通信,服务端专用,监听新 TCP 连接,每一个新连接都会创建一个 SocketChannel
Buffer
1、缓冲 Channel 的读写数据
(1)Java NIO 中的 Buffer 用于和 NIO 通道进行交互
(2)数据是从通道读入缓冲区,从缓冲区写入到通道中的
2、本质
(1)一块可以写 / 读数据的内存
(2)这块内存被包装成 NIO Buffer 对象,并提供一组方法,用来访问该块内存
(3)缓冲区实际上是一个容器对象,即一个数组
(4)在 NIO 库中,所有数据都是用缓冲区处理,直接读 / 写缓冲区;任何时候访问 NIO 中的数据,都是将它放到缓冲区中
(5)在面向流 I/O 系统中,所有数据都是直接写 / 读 Stream 对象
3、ByteBuffer(常用)
(1)抽象类,以字节为单位缓冲数据
(2)父类:Buffer
(3)实现类:MappedByteBuffer、DirectByteBuffer、HeapByteBuffer
4、缓冲不同数据类型(不常用)
(1)ShortBuffer
(2)IntBuffer
(3)LongBuffer
(4)FloatBuffer
(5)DoubleBuffer
(6)CharBuffer
BIO 服务器端
1、多线程设计
(1)服务器端为每个客户端连接,都创建单独的线程,分别去处理对应 Socket 连接
(2)缺点:每个线程都需要占用一定的内存,当连接较多时,会开辟大量线程,导致占用大量内存;线程上下文切换成本高
(3)只适合连接数少的场景
2、线程池设计
(1)一个线程可以有多个 Socket 连接
(2)缺点:阻塞模式下,线程仅能处理一个 Socket 连接,线程池中的线程获取任务(task)后,只有当其执行完任务之后(即断开连接后),才会去获取并执行下一个任务,若 Socke 连接一直未断开,则其对应的线程无法处理其他 Socket 连接
(3)仅适合短连接场景:短连接即建立连接发送请求并响应后就立即断开,使得线程池中的线程可以快速处理其他连接
Selector
1、选择器 / 多路复用器
2、作用
(1)检查一个或多个 NIO Channel(通道)状态是否处于可读、可写
(2)实现单线程管理多个 Channel,即管理多个网络链接
(3)使用更少线程处理通道,避免了线程上下文切换带来的开销
3、使用
(1)使用前,向 Selector 注册 Channel,然后调用 Selector 的 select()
(2)配合一个线程来管理多个 Channel(FileChannel 因为是阻塞式,所以无法使用 Selector),获取多个 Channel 上发生的事件
(3)这些 Channel 工作在非阻塞模式下,当一个 Channel 中没有执行任务时,可以去执行其他 Channel 中的任务
(4)若事件未就绪,调用 Selector 的 select() 会阻塞线程,直到 Channel 发生读写就绪事件,select() 就会返回这些事件,交给 thread 来处理
4、适合连接数多,但流量较少的场景
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战