Java nio 空轮询bug

这个应该是很老的bug了,linux平台,jdk6好像就修复了

bug 描述 :https://bugs.java.com/bugdata...

This is an issue with poll (and epoll) on Linux. If a file descriptor for a connected socket is polled with a request event mask of 0, and if the connection is abruptly terminated (RST) then the poll wakes up with the POLLHUP (and maybe POLLERR) bit set in the returned event set. The implication of this behaviour is that Selector will wakeup and as the interest set for the SocketChannel is 0 it means there aren't any selected events and the select method returns 0.

之前一直不知道event mask 为0 代表啥,知道翻到了资料

http://man7.org/linux/man-pag...

The field events is an input parameter, a bit mask specifying the
events the application is interested in for the file descriptor fd.
This field may be specified as zero, in which case the only events
that can be returned in revents are POLLHUP, POLLERR, and POLLNVAL
(see below).

大概知道了0代表了POLLHUP, POLLERR, and POLLNVA 这些event

继续查阅https://blog.csdn.net/tilter/...

常量 说明
POLLIN 普通或优先级带数据可读
POLLRDNORM 普通数据可读
POLLRDBAND 优先级带数据可读
POLLPRI 高优先级数据可读
POLLOUT 普通数据可写
POLLWRNORM 普通数据可写
POLLWRBAND 优先级带数据可写
POLLERR 发生错误
POLLHUP 对方描述符挂起
POLLNVAL 描述字不是一个打开的文件

大概明白了Bug描述中 abruptly terminated (RST)的含义及发生场景

也就知道什么时候会发生空轮询bug

个人记录下


还有1问题没想明白,为啥先cancel,再select(or selectNow) 还是无法避免这个问题? ref: https://www.cnblogs.com/JAYIT...
网上说,在多线程环境下,selectNow先发生,cancel后发生,这样还是会存在问题
但是,即使cancel后发生,channel也会被移到待移除channel集合了,下次再轮询的时候,select也会出发这个集合里面的channel被清除
这样,最多多一次空轮训。
目前给的方案都是open一个新的selector,把有效的channel全部注册到新的selector,再轮询新的selector

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值