Selector.select
创建Selector
Selector selector = Selector.open();
selector.select()
select() = select(0) = lockAndDoSelect(-1) = doSelect(-1)
public int select() throws IOException {return this.select(0L);
}
public int select(long var1) throws IOException {if (var1 < 0L) {throw new IllegalArgumentException("Negative timeout");} else {return this.lockAndDoSelect(var1 == 0L ? -1L : var1);}
}
selectNow()
selectNow = lockAndDoSelect(0L) = doSelect(0)
其他超时
假设是select(5) = lockAndDoSelect(5) = doSelect(5)
在这里插入代码片
SelectorImpl
最终调用doSelect(timeout)
private int lockAndDoSelect(long timeout) throws IOException {synchronized (this) {if (!isOpen())throw new ClosedSelectorException();synchronized (publicKeys) {synchronized (publicSelectedKeys) {return doSelect(timeout);}}}
}
EPollSelectorImpl
doSelect
protected int doSelect(long timeout) throws IOException { // select(0)=-1 selectNow():0if (closed)throw new ClosedSelectorException();processDeregisterQueue();try {begin();pollWrapper.poll(timeout);} finally {end();}processDeregisterQueue();int numKeysUpdated = updateSelectedKeys();if (pollWrapper.interrupted()) {// Clear the wakeup pipepollWrapper.putEventOps(pollWrapper.interruptedIndex(), 0);synchronized (interruptLock) {pollWrapper.clearInterrupted();IOUtil.drain(fd0);interruptTriggered = false;}}return numKeysUpdated;
}
processDeregisterQueue
处理cancel的事件
# SelectorImpl
void processDeregisterQueue() throws IOException { // 处理cancelledKeys// Precondition: Synchronized on this, keys, and selectedKeysSet<SelectionKey> cks = cancelledKeys();synchronized (cks) {if (!cks.isEmpty()) {Iterator<SelectionKey> i = cks.iterator();while (i.hasNext()) {SelectionKeyImpl ski = (SelectionKeyImpl)i.next();try {implDereg(ski); //取消注册} catch (SocketException se) {throw new IOException("Error deregistering key", se);} finally {i.remove();}}}}
}
EPollSelectorImpl.implDereg
protected void implDereg(SelectionKeyImpl ski) throws IOException {assert (ski.getIndex() >= 0);SelChImpl ch = ski.channel; // 得到channelint fd = ch.getFDVal(); // 得到fdfdToKey.remove(Integer.valueOf(fd)); // 从map删除文件描述符和的SelectionKey的映射关系pollWrapper.remove(fd); // EPOLL_CTL_DEL remove from epollski.setIndex(-1);keys.remove(ski); //从注册的Selector删除本SelectionKeyselectedKeys.remove(ski); // 从已就绪的事件列表中删除本SelectionKeyderegister((AbstractSelectionKey)ski); // AbstractSelector.deregister调用 最终((AbstractSelectableChannel)key.channel()).removeKey(key) 从Channel删除该SelectionKeySelectableChannel selch = ski.channel();if (!selch.isOpen() && !selch.isRegistered())((SelChImpl)selch).kill();
}
EPollArrayWrapper
/*** Remove a file descriptor*/
void remove(int fd) {synchronized (updateLock) {// kill pending and future update for this file descriptorsetUpdateEvents(fd, KILLED, false);// remove from epollif (registered.get(fd)) {epollCtl(epfd, EPOLL_CTL_DEL, fd, 0);registered.clear(fd);}}
}
poll
int poll(long timeout) throws IOException {updateRegistrations();// int epoll_wait(int epfd, struct epoll_event * events, intmaxevents, int timeout);// timeout是超时时间(毫秒,0:立即返回,-1:一直阻塞updated = epollWait(pollArrayAddress, NUM_EPOLLEVENTS, timeout, epfd);for (int i=0; i<updated; i++) {if (getDescriptor(i) == incomingInterruptFD) {interruptedIndex = i;interrupted = true;break;}}return updated;}
Selector.select相关推荐
- selector.select()和selector.selectedKeys()
当调用selector.select()时会阻塞: This method performs a blocking selection operation. It returns only after ...
- Selector.select()
Netty的底层依然是依赖于JDK的NIO . 开发NIO服务端的代码如下所示 import java.io.IOException; import java.net.InetSocketAddres ...
- java nio原理 epoll_多路复用 Select Poll Epoll 的实现原理(BIO与NIO)
BIO blocking阻塞的意思,当我们在后端开发使用的时候,accetp 事件会阻塞主线程. 当accept事件执行的时候,客户的会和服务建立一个socket 连接.一般后端就会开启一个线程执行后 ...
- jquery操作select取值赋值与设置选中[转]
本节内容: jquery实现select下拉框的取值与赋值,设置选中的方法大全. 比如<select class="selector"></select> ...
- Java NIO系列教程(六) Selector
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 下面是 ...
- Java NIO Selector 详解
Selector 允许一个单一的线程来操作多个 Channel,如果我们的应用程序中使用了多个 Channel,那么使用 Selector 很方便的实现这样的目的,但是因为在一个线程中使用了多个 Ch ...
- python协程框架_[记录]python的简单协程框架(回调+时间循环+select)
# -*- coding: utf-8 -*- # @Time : 2018/12/15 18:55 # @File : coroutine.py #一个简单的 Coroutine 框架 import ...
- 【NIO】Selector
经过前边几节的介绍,我相信大家都掌握了IO多路复用的核心思想了.昨天我给了一个使用C语言进行 linux 编程的IO多路复用的例子.那个例子使用的是 poll 这个系统调用,今天我会给出一个使用Jav ...
- java nio Selector (新IO)分析
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件.这样,一个单独的线程可以管理多个channel,从而管理多个网络连接. 为什么 ...
最新文章
- python使用imbalanced-learn的AllKNN方法进行下采样处理数据不平衡问题
- lampp mysql 等待响应时间很长,XAMPP 最大执行时间(max_execution_time) 问题
- 微软计划使用 Rust 取代 C和C+
- 手写简版spring --5--资源加载器解析文件注册对象
- html格式文档结构保存数据库6,freeCAD文档结构
- Linux中使用tar打包解包查看的使用方法
- 生物学家、钢管舞、全栈工程师,女程序员如何活得漂亮
- 机器学习基础算法24-SVM理论部分
- chrome应用商店打不开_Chrome 浏览器必备“扩展管理工具”,一键管理 Chrome 扩展...
- windows mysql 5.5 升级_windows环境mysql5.0晋级mysql5.5
- RUP软件开发生命周期
- 机器学习(1):knn算法总结
- WX系列无线漫游的配置
- 3.3 RESET and Initialization Procedure
- python列表字符全部改为大写_将包含字符串的Python列表转换为小写或大写
- RocketMQ 消息发送system busy、broker busy原因分析与解决方案
- IP、 TCP、 UDP协议
- 机器视觉——入门基础(一)—— 相机篇
- 相位同步、频率同步、同相位时钟、同源时钟、同时钟域时钟和异步时钟区别。
- EOJ3054-波兰式求值(递归法)
热门文章
- vscode的插件存储位置
- 最新uni-app实战仿糗事百科app开发教程完整版
- JDK安装和配置教程
- 元器件TVS管与ESD静电二极管的三处不同,你知道吗?
- 【Python】高级特性 一
- 十一长假去旅行,不知如何规划?三个步骤,用思维导图来规划旅行路线
- Android 9.0 Adaptive Icon 圆形图标剪切不全问题(上下左右部分被裁减)
- c 语言趣味入门,Cc++趣味程序百例(献给CC++初学者).doc
- 花170美元,我了解了消费级间谍软件的世界
- 基于精益生产模式的服装生产计划管理