简体   繁体   中英

Java: SelectionKey.interestOps(int) not thread safe?

In my application I use multiple threads to handle client connections.

i found a very weird behavior when debugging - I have a SelectionKey that by invoking (using the debugger) its interestOps() method the return value is 1 (READ), but when I send data to the socket corresponding to that key the selector not wakes up..

If using the debugger I changes the specific selection key interest ops to 1 (even though it was 1) the selector suddenly react to that change.

I have only one thread handling a connection at a given time but this thread is not specific to that connection, if I disable the multi-threading (set the thread pool to be of size 1) this problem never occurred.

By looking at the SelectionKey class documentation - this method should be thread safe - did i miss something?

It's not a question of thread safety. If there is a select() currently in progress, it has already read all the interestOps out of all the registered keys and is selecting on those values as they were when read: the values are passed to the operating system and an operating system blocking operation is in progress. Changing the interestOps in the middle of a select operation can't affect that select operation, only the next one(s).

The problem was solved after i moved all the changes to the interestOps to be done on the selector thread - so I guess that interestOps(int) is not thread safe.

Edit
by moving all the interestOps changes to the selector thread I also gain 30% speedup - not sure why but this is the only change between my tests..

I'm a little bit late to the party, but for people who will, like me, visit in the future:

"Selection keys are safe for use by multiple concurrent threads. The operations of reading and writing the interest set will, in general, be synchronized with certain operations of the selector."

Taken from "SelectionKey in Java 7"

(Sorry for the late comment, but I think it's better to clarify) As the javadoc said ( https://docs.oracle.com/javase/8/docs/api/java/nio/channels/SelectionKey.html ):

Exactly how this synchronization is performed is implementation-dependent: In a naive implementation, reading or writing the interest set may block indefinitely if a selection operation is already in progress; in a high-performance implementation, reading or writing the interest set may block briefly, if at all. In any case, a selection operation will always use the interest-set value that was current at the moment that the operation began.

So to fully understand the original question, we'll need to know in which enviroment (OS, kernel version, jdk version) it is happening.

(Sorry I should send it as inline comment, but I'm not allowed to)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM