面试题答案
一键面试Selector多路复用工作原理
- 注册机制:在Java NIO中,
Selector
可以监控多个Channel
的事件。首先,Channel
必须设置为非阻塞模式,然后将其注册到Selector
上,并指定要监听的事件类型(通过SelectionKey
的操作集)。例如,一个SocketChannel
可以注册到Selector
上监听读事件(OP_READ
)。 - 轮询机制:
Selector
使用轮询的方式不断检查注册在其上的Channel
是否有感兴趣的事件发生。当Selector
的select()
方法被调用时,它会阻塞等待,直到至少有一个注册的Channel
上有事件发生,或者超过指定的等待时间(如果设置了超时参数)。 - 事件通知:当有事件发生时,
select()
方法返回,并且Selector
会通过selectedKeys()
方法返回一个包含发生事件的SelectionKey
的集合。应用程序可以遍历这个集合,获取每个SelectionKey
,并判断其对应的Channel
发生了什么事件,然后进行相应的处理。
SelectionKey操作集的使用场景
- OP_READ:
- 场景:当需要从
Channel
读取数据时使用。例如,在服务器端接收客户端发送的数据,当客户端有数据发送过来时,注册了OP_READ
的SocketChannel
会被Selector
检测到有可读事件,应用程序可以从该Channel
读取数据。
- 场景:当需要从
- OP_WRITE:
- 场景:当需要向
Channel
写入数据时使用。在非阻塞 I/O 中,由于Channel
可能不会一次性将所有数据发送出去,当Channel
可写时(即底层缓冲区有空间),注册了OP_WRITE
的Channel
会被Selector
检测到,应用程序可以继续向Channel
写入剩余的数据。
- 场景:当需要向
- OP_CONNECT:
- 场景:用于
SocketChannel
连接服务器时。当SocketChannel
发起连接操作(connect()
)后,在非阻塞模式下,连接可能不会立即建立成功。通过注册OP_CONNECT
,Selector
可以检测连接操作是否完成,应用程序可以在连接成功后进行后续操作,比如发送初始数据等。
- 场景:用于
- OP_ACCEPT:
- 场景:仅用于
ServerSocketChannel
。当有新的客户端连接请求到达服务器时,注册了OP_ACCEPT
的ServerSocketChannel
会被Selector
检测到,服务器可以调用accept()
方法接受新的连接,并创建对应的SocketChannel
进行后续通信。
- 场景:仅用于