NIO 中 selector 的概念
NIO 中 selector 的概念
程序员朱永胜有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步, 认准
https://blog.zysicyj.top
全网最细面试题手册,支持艾宾浩斯记忆法。这是一份最全面、最详细、最高质量的 java 面试题,不建议你死记硬背,只要每天复习一遍,有个大概印象就行了。https://store.amazingmemo.com/chapterDetail/1685324709017001`
NIO 中的 Selector 概念
在 Java NIO 中,Selector是一个高级工具,它可以检测一个或多个 NIO 通道(Channel),并能够知晓通道是否为诸如读取、写入等操作做好准备。这种机制使得单个线程可以管理多个通道,因此也可以管理多个网络连接。
为什么使用 Selector?
在传统的 IO 模型中,每个连接创建时都需要一个线程去处理,当并发的连接数增加时,线程数也会线性增加,这会带来线程上下文切换和资源消耗的问题。而使用 Selector 能够通过一个线程来处理多个通道,极大地减少了资源的消耗,提高了程序的效率。
Selector 的工作原理
Selector 内部使用了一种叫做 多路复用 的技术。在这种模式下,Selector 会询问每个注册的通道是否有事件准备就绪。如果有,它会集中处理这些事件,这样就可以只用一个单独的线程来管理多个通道的事件。
如何使用 Selector
以下是使用 Selector 的基本步骤:
打开 Selector
1
Selector selector = Selector.open();
向 Selector 注册通道
首先,通道必须设置为非阻塞模式,因为阻塞模式的通道不能与 Selector 一起使用。然后,通道可以注册到 Selector 上:1
2channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);选择就绪的通道
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19while(true) {
int readyChannels = selector.select();
if(readyChannels == 0) continue;
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
} else if (key.isConnectable()) {
// a connection was established with a remote server.
} else if (key.isReadable()) {
// a channel is ready for reading
} else if (key.isWritable()) {
// a channel is ready for writing
}
keyIterator.remove();
}
}
在这个循环中,selector.select()
是一个阻塞调用,只有至少有一个通道就绪时才会返回。selectedKeys
集合包含了所有就绪的通道的 SelectionKey,然后通过迭代器可以遍历这些键,检查通道就绪的事件类型,并相应地进行处理。
总结
Selector 是 Java NIO 中的核心组件之一,它允许单线程有效地管理多个通道,从而处理多个网络连接。这种模型在需要处理成千上万个连接的高性能网络服务器中非常有用。正确使用 Selector 可以使应用程序更加高效,响应更快,且更加可扩展。