java为什么不解决空轮询,netty解决空轮询bug
selector在没有结果的情况下,依然被唤醒,导致一直空轮询,cpu100%
直接定位到NioEventLoop
@Override
protected void run() {
for (;;) {
try {
switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {
case SelectStrategy.CONTINUE:
continue;
case SelectStrategy.SELECT:
select(wakenUp.getAndSet(false));
if (wakenUp.get()) {
selector.wakeup();
}
default:
// fallthrough
}
cancelledKeys = 0;
needsToSelectAgain = false;
final int ioRatio = this.ioRatio;
if (ioRatio == 100) {
try {
processSelectedKeys();
} finally {
// Ensure we always run tasks.
runAllTasks();
}
} else {
final long ioStartTime = System.nanoTime();
try {
processSelectedKeys();
} finally {
// Ensure we always run tasks.
final long ioTime = System.nanoTime() - ioStartTime;
runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
}
}
} catch (Throwable t) {
handleLoopException(t);
}
try {
if (isShuttingDown()) {
closeAll();
if (confirmShutdown()) {
return;
}
}
} catch (Throwable t) {
handleLoopException(t);
}
}
}
第二个case,SelectStrategy.SELECT ,其值为-1。跟进调用的select方法。
private void select(boolean oldWakenUp) throws IOException {
Selector selector = this.selector;
try {
int selectCnt = 0;
long currentTimeNanos = System.nanoTime();
long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos);
for (;;) {
long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L;
if (timeoutMillis <= 0) {
if (selectCnt == 0) {
selector.selectNow();
selectCnt = 1;
}
break;
}
if (hasTasks() && wakenUp.compareAndSet(false, true)) {
selector.selectNow();
selectCnt = 1;
break;
}
int selectedKeys = selector.select(timeoutMillis);
selectCnt ++;
if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) {
break;
}
if (Thread.interrupted()) {
if (logger.isDebugEnabled()) {
logger.debug("Selector.select() returned prematurely because " +
"Thread.currentThread().interrupt() was called. Use " +
"NioEventLoop.shutdownGracefully() to shutdown the NioEventLoop.");
}
selectCnt = 1;
break;
}
long time = System.nanoTime();
if (time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos) {
// timeoutMillis elapsed without anything selected.
selectCnt = 1;
} else if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 &&
selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
// The selector returned prematurely many times in a row.
// Rebuild the selector to work around the problem.
logger.warn(
"Selector.select() returned prematurely {} times in a row; rebuilding Selector {}.",
selectCnt, selector);
rebuildSelector();
selector = this.selector;
// Select again to populate selectedKeys.
selector.selectNow();
selectCnt = 1;
break;
}
currentTimeNanos = time;
}
if (selectCnt > MIN_PREMATURE_SELECTOR_RETURNS) {
if (logger.isDebugEnabled()) {
logger.debug("Selector.select() returned prematurely {} times in a row for Selector {}.",
selectCnt - 1, selector);
}
}
} catch (CancelledKeyException e) {
if (logger.isDebugEnabled()) {
logger.debug(CancelledKeyException.class.getSimpleName() + " raised by a Selector {} - JDK bug?",
selector, e);
}
// Harmless exception - log anyway
}
}
上述代码中在轮询之前,先定义当前时间currentTimeNanos。接着计算出一个执行最少需要的时间timeoutMillis。每次对selectCnt做++操作。
在后面的代码中通过
time - TimeUnit.MILLISECONDS.toNanos(timeoutMillis) >= currentTimeNanos
进行判断,如果到达执行到最少时间,则seletCnt重置为1。一旦到达SELECTOR_AUTO_REBUILD_THRESHOLD这个阀值,就需要重建selector来解决这个问题。这个阀值默认是512。
java为什么不解决空轮询,netty解决空轮询bug相关推荐
- Netty解决TCP的粘包和分包(二)
2019独角兽企业重金招聘Python工程师标准>>> Netty解决TCP的粘包和分包(二) 使用LengthFieldBasedFrameDecoder解码器分包 先看一下这个类 ...
- Netty解决TCP粘包/拆包导致的半包读写问题
一.TCP粘包/拆包问题说明 TCP是个"流"协议,就是没有界限的一串数据.TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包拆分,所以在业务上认为,一 ...
- java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 解决方法 java.lang.ClassNotFoundException: com.
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 解决方法 java.lang.ClassNotFoundException: com.m ...
- java无阻塞执行脚本,JAVA调用Shell脚本-及阻塞的解决方法
JAVA调用Shell脚本--及阻塞的解决办法 用java调用shell,使用 Process p=Runtime.getRuntime().exec(String[] cmd); Runtime.e ...
- Adobe flash cs5 的Java运行时环境初始化错误 完美解决方法
Adobe flash cs5 的Java运行时环境初始化错误 完美解决方法 下载网络上的Adobe flash cs5 精简版(绿色版),Java运行时环境初始化时出现错误,你可能需要重装Flash ...
- java开发中遇到的问题及解决方法(持续更新)
java开发中遇到的问题及解决方法(持续更新) 参考文章: (1)java开发中遇到的问题及解决方法(持续更新) (2)https://www.cnblogs.com/LiuYanYGZ/p/6112 ...
- Android DialogFragment 遇到 java.lang.IllegalStateException: Fragment already added: 的解决方法
Android DialogFragment 遇到 java.lang.IllegalStateException: Fragment already added: 的解决方法 参考文章: (1)An ...
- java.net.UnknownHostException: unknown host:xxxx异常解决办法
java.net.UnknownHostException: unknown host:xxxx异常解决办法 参考文章: (1)java.net.UnknownHostException: unkno ...
- Idea运行web项目时,提示java.lang.ClassNotFoundException: com.mysql.jdbc.Driver解决方法
Idea运行web项目时,提示java.lang.ClassNotFoundException: com.mysql.jdbc.Driver解决方法 参考文章: (1)Idea运行web项目时,提示j ...
最新文章
- svn: Working copy locked
- Firebug Console 与命令行全集
- 360脱口秀:‘未来属于虚拟’开播啦!
- catia 快捷键 激活零件_CATIA基本操作技巧
- 轻松得到C# ADO.NET的各种数据库连接字符串
- [黑马程序员二]:C#面向对象基础
- 异常规范之阿里巴巴开发手册中的异常规范讲解
- 数据结构之希尔排序------java实现
- [Cordova]JS和Native交互实现关键代码(iOS)
- 启动NameNode和DataNode
- EVCache缓存在 Spring Boot中的实战
- 荷兰铁路在采纳敏捷和精益中的做法
- Linux中下载,压缩,解压等命令
- java 栈泛型_使用泛型实现栈结构
- 常见API漏洞解释以及应用层解决方案
- 汉字转拼音,多音字解决方案
- Altium Designer入门与进阶教程系列
- 【网络安全】黑客攻防与入侵检测(练习题)
- 《计算机网络自顶向下》Socket Lab2 UDP Pinger Lab
- php 中断请求,PHP 信号中断系统
热门文章
- 超炫酷的Markdown渲染阅读工具(附开源地址)
- 由粗模生细模 精灵4 RTK结合PhotoScan航线规划生成精细化模型
- 三位分节制顺口溜_小学数学学习中36类顺口溜,说给孩子听
- vysor无线连接投屏使用/wifi连接+Vysor_2.1.2Pro安装教程+谷歌vysor插件防止自动更新
- 恒源云(Gpushare)_如何查看显卡占用的情况?技巧大放送2
- 上计算机课如何摆脱桌面控制,(信息老师必读)防止学生摆脱电子教室控制的方法、信息课怎样防止学生不受控制...
- MySQL存储引擎与数据的关系_MySQL存储引擎与数据类型
- js replace正则替换 \n
- python 最小堆类型: heapq
- git命令行账号切换