当前位置:网站首页>NIO's Selector execution process
NIO's Selector execution process
2022-08-02 21:04:00 【i attack siege lion】
一、Seletor是什么?
selector 单从字面意思不好理解,Seletor是一个监听器,它可以监听Channel中发生的事件.Channelcan be registered atSeletor中,when these are registeredChannel在事件发生时,Seletor的select 方法就会返回这些事件交给 thread 来处理.
二、Seletordifference from multithreading
It is not easy to understand just from the above explanation,需要结合服务器的设计演化来理解它的用途
多线程版设计
to clients in the networksocket请求,If each request opens a thread to handle,Then the system memory usage is high,Thread context switching costs are also high,The stress on the system can be very high.
线程池版设计
使用线程池,Optimized thread creation,But in blocking mode,线程仅能处理一个 socket 连接, 仅适合短连接场景
selector版本
selector 的作用就是配合一个线程来管理多个 channel,获取这些 channel 上发生的事件,这些 channel 工作在非阻塞模式下,不会让线程吊死在一个 channel 上.适合连接数特别多,但流量低的场景(low traffic)
三、selector单线程处理多socket案例
服务端代码:
@Slf4j
public class ChannelDemo6 {
public static void main(String[] args) {
try (ServerSocketChannel channel = ServerSocketChannel.open()) {
channel.bind(new InetSocketAddress(8080));
System.out.println(channel);
Selector selector = Selector.open();
channel.configureBlocking(false);
channel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
int count = selector.select();
log.debug("select count: {}", count);
// 获取所有事件
Set<SelectionKey> keys = selector.selectedKeys();
// 遍历所有事件,逐一处理
Iterator<SelectionKey> iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
// 判断事件类型
if (key.isAcceptable()) {
ServerSocketChannel c = (ServerSocketChannel) key.channel();
// 必须处理
SocketChannel sc = c.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
log.debug("连接已建立: {}", sc);
}
else if (key.isReadable()) {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(128);
int read = sc.read(buffer);
if(read == -1) {
key.cancel();
sc.close();
} else {
buffer.flip();
debugAll(buffer);
}
}
// 处理完毕,必须将事件移除
iter.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8080)) {
System.out.println(socket);
socket.getOutputStream().write("world".getBytes());
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
方法解释:
- ServerSocketChannelused to create the serverChannel,它有点像ServerSocket.
- channel.configureBlocking(false);设置channel为非阻塞,这样如果accpet的时候,如果没有连接,就会返回null.
- channel.register(selector, SelectionKey.OP_ACCEPT)将channel注册到selector中,监听accept连接事件
- selector.select(),会阻塞,等待客户端连接
- selector.selectedKeys(),event production,will add events to this collection
四、selector事件
- accept Fired when a connection is made
- connect Fired when a client establishes a connection
- read Raises a readable event when a client message is received
- 可写事件
边栏推荐
猜你喜欢
How a "cloud" can bring about new changes in the industry
手机银行体验性测试:如何获取用户真实感受
LeetCode 2333. 最小差值平方和(贪心)
Data Governance: The Evolution of Data Integration and Application Patterns
千万级QPS下服务如何才能平滑启动
数据治理:数据集成和应用模式的演进
回收站删除的文件怎么恢复,2个方法汇总助您快速解决
“12306”的架构到底有多牛逼?
mongodb的游标
[论文分享] VideoFlow: A Flow-Based Generative Model for Video
随机推荐
Go 语言快速入门指南:第二篇 变量与常量
golang刷leetcode 经典(4) 实现跳表
影响PoE供电传输距离的除了网线还有啥?
织梦自定义表单添加全选和全不选功能按钮
TSF微服务治理实战系列(一)——治理蓝图
golang刷leetcode动态规划(10)编辑距离
LeetCode 2336. 无限集中的最小数字(SortedSet)
如何构建准实时数仓?
redis总结_分布式缓存
Playing in the cloud | The key technology of Tianyi cloud object storage ZOS high availability is revealed
详细教学——1688关键词搜索API操作流程
KunlunBase 1.0 is released!
golang刷leetcode动态规划(9)不同路径 II
基于HDF的LED驱动程序开发(1)
Enterprise cloud cost control, are you really doing it right?
天翼云4.0来了!千城万池,无所不至!
STL案例-招聘新员工
织梦提示信息提示框美化
POE交换机全方位解读(中)
就刚刚,鸿蒙3.0发布了,华为还一口气发布了十一款产品