In my implementation of Java NIO I have not been able to get SelectionKey.attach() to work. Basically, once clients connect (OP_ACCEPT interest ops) I add them to a map where their IP address maps to an object that maintains state for the client. Then, when an OP_READ occurs, I again retrieve the client's IP address, and this time get the value from the map and get the client's state object that way.
The problem here is that I have to do a map lookup EVERY TIME data is read from the network. There is a lot of wasted work going on there. So, I was thrilled to see that you can attach an arbitrary object type to a SelectionKey, which should be easily retrieved when you call SelectionKey.attachment(), even if we are now handling a different event (retrieved during OP_READ versus put into the map during OP_ACCEPT).
The problem is that it doesn't work. When I retrieve the attachment, it is always null. And if I set up the attachment via attach() and then immediately call attachment(), it does work. Somehow between different events, it loses its association.
I'm sorry, my code is a bit long to post here, but if you look at the comments in this thread: link text ...You will see that some others have basically come to the same conclusion: that attach() and attachment() don't work, and never have.
Is there a trick to get it to work, or am I stuck with the evil overhead necessary of manually doing a lookup in a map EVERY TIME there is a new read event to handle?
Finally, is there a way to "wrap" SelectionKey in a new subclass that will properly handle attach() and attachment()?
I have successfully attached objects to SelectionKeys without any problems, but only from the same event. For example the first time I get an
OP_READ, I attach an object to the SelectionKey and on subsequent reads I retrieve it, and it works fine. Maybe
OP_READ handle different keys because they're different events, but I think the SelectionKey should be the same for the same connection... however if you make different connections even from the same IP you will get different SelectionKeys.
UPDATE: I just checked my code and there is something very important: I didn't call attach() at all; I used the
SelectableChannel.register(Selector sel, int ops, Object att) method. If you do that, subsequent calls to attachment() on the SelectionKey will work.