Я нашел пример кода 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);
}
}
Когда он получает выбранные ключи, он удаляет ключ в цикле. Почему мы должны это делать?
UPDATE
Благодаря ответам EJP и user270349, я думаю, что сейчас понимаю, позвольте мне объяснить это подробно.
В селекторе есть 2 таблицы:
-
регистрационная таблица: при вызове
channel.register
в нее будет добавлен новый элемент (ключ). Только если мы назовемkey.cancel()
, он будет удален из этой таблицы. -
готов к таблице выбора: когда мы вызываем
selector.select()
, селектор будет искать таблицу регистрации, найти доступные ключи, скопировать ссылки на них в эту таблицу выбора. Элементы этой таблицы не будут очищаться с помощью селектора (это означает, что даже если мы снова назовемselector.select()
, он не очистит существующие элементы)
Вот почему мы должны вызывать iter.remove()
, когда мы получили ключ из таблицы выбора. Если нет, мы снова и снова получаем ключ selector.selectedKeys()
, даже если он не готов к использованию.