這個應該是很老的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