展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

Selector(选择器)

  • 简介
1) Java 的 NIO,用非阻塞的 IO 方式。可以用一个线程,处理多个的客户端连接,就会使用到Selector(选择器)
2) Selector 能够检测多个注册的通道上是否有事件发生(注意:多个Channel以事件的方式可以注册到同一个Selector),如果有事件发生,便获取事件然
后针对每个事件进行相应的处理。这样就可以只用一个单线程去管理多个通道,也就是管理多个连接和请求。
3) 只有在 连接/通道 真正有读写事件发生时,才会进行读写,就大大地减少了系统开销,并且不必为每个连接都创建一个线程,不用去维护多个线程
4) 避免了多线程之间的上下文切换导致的开销

  • 特点
1) Netty 的 IO 线程 NioEventLoop 聚合了 Selector(选择器,也叫多路复用器),可以同时并发处理成百上千个客户端连接。
2) 当线程从某客户端 Socket 通道进行读写数据时,若没有数据可用时,该线程可以进行其他任务。
3) 线程通常将非阻塞 IO 的空闲时间用于在其他通道上执行 IO 操作,所以单独的线程可以管理多个输入和输出通道。
4) 由于读写操作都是非阻塞的,这就可以充分提升 IO线程的运行效率,避免由于频繁 I/O 阻塞导致的线程挂起。
5) 一个 I/O 线程可以并发处理 N 个客户端连接和读写操作,这从根本上解决了传统同步阻塞 I/O 一连接一线程模型,架构的性能、弹性伸缩能力和可靠性都得到了极大的提升。
  • Selector类相关方法
Selector 类是一个抽象类, 常用方法和说明如下:
    public abstract class Selector implements Closeable {
    public static Selector open();//得到一个选择器对象
    public int select(long timeout);//监控所有注册的通道,当其中有 IO 操作可以进行时,将对应的 SelectionKey 加入到内部集合中并返回,参数用来设置超时时间,该方法是取到有事件发生的通道
    public Set<SelectionKey> selectedKeys();//从内部集合中得到所有的 SelectionKey,也就是返回所有的通道
}
  • selector和线程关联,selector调用selet方法,会返回1个SelectionKey的集合,每个SelectionKey对应不同的事件,通过SelectionKey可以取到对应的通道

  • 注意点

1) NIO中的 ServerSocketChannel功能类似ServerSocket,SocketChannel功能类似Socket
2) selector 相关方法说明

selector.select()//阻塞
selector.select(1000);//阻塞1000毫秒,在1000毫秒后返回
selector.wakeup();//唤醒selector
selector.selectNow();//不阻塞,立马返还
  • (Selector、SelectionKey、ServerScoketChannel和SocketChannel) 关系梳理图
1. 当客户端连接时,会通过ServerSocketChannel 得到 SocketChannel
2. Selector 进行监听 select 方法, 返回有事件发生的通道的个数. 3. 将socketChannel注册到Selector上, register(Selector sel, int ops), 一个selector上可以注册多个SocketChannel
4. 注册后返回一个 SelectionKey, 会和该Selector 关联(集合)
5. 进一步得到各个 SelectionKey (有事件发生)
6. 在通过 SelectionKey 反向获取SocketChannel , 方法 channel()
7. 可以通过 得到的 channel , 完成业务处理
posted @ 2022-08-04 17:27  DogLeftover  阅读(178)  评论(0编辑  收藏  举报