为什么在 Java NIO Selector 中用 iterator.remove() 迭代 SelectionKey

Why iterate SelectionKey with iterator.remove() in Java NIO Selector

以下代码从 HBase RpcServer.java 中删除。我无法理解 loop.Are 每次删除 SelectionKey 有一些原因?这是优化吗?

      try {
      selector.select();

      Iterator<SelectionKey> it = selector.selectedKeys().iterator();

      while (it.hasNext()) {
        SelectionKey key = it.next();
        it.remove();
        if (key.isValid()) {
          if (key.isReadable()) {
            doRead(key);
          }
        }
      }

    } catch (IOException e) {
      LOG.warn("Run into IOExpection in " + name, e);
    }

selectedKeys 的结果包含当前可用于其所选操作的通道键(例如 READWRITE)。如果您不删除密钥,它将保留在集合中,并且下一次调用 select()(和系列)仍将包括它,即使关联的通道尚未准备好进行所选操作。

来自 Selector 的文档:

A selectable channel's registration with a selector is represented by a SelectionKey object. A selector maintains three sets of selection keys:

  • The key set contains the keys representing the current channel registrations of this selector. This set is returned by the keys method.
  • The selected-key set is the set of keys such that each key's channel was detected to be ready for at least one of the operations identified in the key's interest set during a prior selection operation. This set is returned by the selectedKeys method. The selected-key set is always a subset of the key set.

[..]

Keys are added to the selected-key set by selection operations. A key may be removed directly from the selected-key set by invoking the set's remove method or by invoking the remove method of an iterator obtained from the set. Keys are never removed from the selected-key set in any other way; they are not, in particular, removed as a side effect of selection operations. Keys may not be added directly to the selected-key set.

(强调我的)