Adams.H
Adams.H

Reputation: 1663

Does the order of event registration in NIO matter?

The canonical way of using a Selector in java NIO is :

  1. regist the a ServerSocketChannel with the SelectionKey.OP_ACCEPT event type .
  2. invoke select method (which block the thread)in a loop method
  3. then when a OP_ACCEPT event happened , and the relative AcceptEventHandler is invoked to accept a SocketChannel
  4. then regist the accepted SocketChannel with the SelectionKey.OP_READ event type.
  5. when a read event happend , the ReadEventHandler handle the inputs and then regist the SocketChannel with a SelectionKey.OP_WRITE event type.

My question is, why don't register three event type at once at the beginning? Does the sequence make any sense?

Upvotes: 1

Views: 111

Answers (2)

misterbiscuit
misterbiscuit

Reputation: 1797

I'm going to try to add something to the conversation.

A ServerSocketChannel can only accept() new connections. OP_READ / OP_WRITE won't do you anything there. I'm pretty sure you can add them but they will just be ignored because the ServerSocketChannel's only responsibility is to accept() remote SocketChannel.

Once you accept() and get a new SocketChannel; you want to listen to OP_READ first. If you listen to OP_WRITE then most likely you will get the OP_WRITE returned to you every single time you call select() and that will consume lots of resources.

You only want to listen to OP_WRITE when you tried to write some data to the SocketChannel and not all the data was written.

Upvotes: 1

user207421
user207421

Reputation: 311023

The canonical way of using a Selector in java NIO is:

No it isn't. See below.

why don't register three event type at once at the beginning?

Because you can't. You don't have the accepted channel until you call accept(), and you don't do that until you have registered OP_ACCEPT and had it fire, and you can't register the accepted channel for anything until you have it.

does the sequence make any sense?

Nothing else would make sense.

NB you don't register OP_WRITE until you've encountered a short or zero-length write. The reason is that it is almost always ready, so the strategy is simply to write when you have something to write, and only use OP_WRITE to tell you when it becomes possible to write again after a short write (which means the socket send buffer was full).

Upvotes: 1

Related Questions