面试题答案
一键面试Selector多路复用实现及工作机制简述
- Selector实现多路复用原理
- Selector是Java NIO中的核心组件,它能够同时监控多个通道(Channel)的I/O事件。通过将多个Channel注册到一个Selector上,Selector可以使用单个线程来处理多个Channel的I/O操作,从而实现多路复用。这避免了为每个Channel创建一个单独的线程,大大减少了线程资源的开销。
- 工作机制
- 注册阶段:
- 首先,将Channel配置为非阻塞模式。例如SocketChannel可以通过
channel.configureBlocking(false)
方法设置为非阻塞。 - 然后,将Channel注册到Selector上,并指定要监听的事件类型,如
SelectionKey.OP_READ
(读事件)、SelectionKey.OP_WRITE
(写事件)等。注册过程通过channel.register(selector, SelectionKey.OP_READ)
这样的代码实现,注册后会返回一个SelectionKey
对象,该对象包含了Channel与Selector的关联信息以及所关注的事件。
- 首先,将Channel配置为非阻塞模式。例如SocketChannel可以通过
- 轮询阶段:
- Selector通过调用
select()
方法来轮询注册在其上的Channel。select()
方法会阻塞当前线程,直到至少有一个注册的Channel上有感兴趣的事件发生,或者经过指定的超时时间(如果调用了select(long timeout)
方法)。 - 当有事件发生时,
select()
方法返回的int值表示发生事件的Channel数量。此时可以通过selector.selectedKeys()
获取发生事件的SelectionKey
集合。
- Selector通过调用
- 处理阶段:
- 遍历
selectedKeys()
返回的集合,对每个SelectionKey
进行处理。通过SelectionKey
可以获取对应的Channel,然后根据SelectionKey
中记录的事件类型进行相应的I/O操作。例如,如果是读事件,可以从Channel中读取数据;如果是写事件,可以向Channel中写入数据。处理完成后,需要从selectedKeys
集合中移除当前处理的SelectionKey
,防止重复处理。
- 遍历
- 注册阶段: