Java nio 空轮询bug

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

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

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 表明啥,知道翻到了资料linux

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 这些eventapp

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

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

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

也就知道何时会发生空轮询bug.net

我的记录下线程


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

相关文章
相关标签/搜索