Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why the key should be removed in `selector.selectedKeys().iterator()` in java nio?

Tags:

java

nio

I found some sample code of java nio:

 ServerSocketChannel server = ServerSocketChannel.open();  
 Selector selector = Selector.open();  
 server.socket().bind(new InetSocketAddress(8080));  
 server.configureBlocking(false); 
 server.register(selector, SelectionKey.OP_ACCEPT);  

 while(true) {
     selector.select(); 
     Iterator iter = selector.selectedKeys().iterator();  
     while (iter.hasNext()) {  
         SelectionKey key = (SelectionKey) iter.next();  
         iter.remove();  // Why remove it? 
         process(key);  
     }
 }

When he gets the selected keys, he remove the key in the loop. Why we should do this?


UPDATE

Thanks to the answers provided by EJP and user270349, I think I understand it now, let me explain it in detail.

There are 2 tables in the selector:

  1. registration table: when we call channel.register, there will be a new item(key) into it. Only if we call key.cancel(), it will be removed from this table.

  2. ready for selection table: when we call selector.select(), the selector will look up the registration table, find the keys which are available, copy the references of them to this selection table. The items of this table won't be cleared by selector(that means, even if we call selector.select() again, it won't clear the existing items)

That's why we have to invoke iter.remove() when we got the key from selection table. If not, we will get the key again and again by selector.selectedKeys() even if it's not ready to use.

like image 515
Freewind Avatar asked Aug 20 '11 13:08

Freewind


1 Answers

Because the Selector never does that, it only adds to the set, so if you don't do it you will reprocess the event yourself next time the Selector returns.

like image 144
user207421 Avatar answered Nov 06 '22 22:11

user207421