Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8204486

(se) select(Consumer<SelectionKey> action) as alternative to selected-key set

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P4
    • Resolution: Approved
    • Fix Version/s: 11
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Risk:
      minimal
    • Compatibility Risk Description:
      New methods, no compatibility risk
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      Summary

      Add three methods to java.nio.channels.Selector to do selection operations that perform an action on the keys of each channel that is ready to perform an operation. The existing select methods add the key to the selector's selected-key set, the new methods are an alternative way to report that a channel is ready to perform an operation.

      Problem

      Adding keys to, and removing keys from, the selector's selected-key set can be a performance issue in many high performance server applications. The Netty framework is one example that works around this by hacking into private fields of the selector implementations in order to inject its own object to collect events. Such hacks will break when the JDK internals are fully encapsulated.

      Solution

      Update the Selector API with a new form of selection operation that invokes an action (represented by a Consumer object) on the keys of each channel that is ready to perform an operation. Three methods analogous to the three existing select and selectNow methods are proposed to be added.

      Specification

      The specdiff for both java.nio.channels.Selector and java.nio.channels.SelectionKey is attached.

      For ease of reviewing, the substantive additions, specifically the main addition to the Selector class description and the three new methods, are inlined here:

      /**
       * <h3>Selection operations that perform an action on selected keys</h3>
       *
       * <p> During each selection operation, keys may be removed from the selector's
       * key, selected-key, and cancelled-key sets.  Selection is performed by the
       * {@link #select(Consumer)}, {@link #select(Consumer,long)}, and {@link
       * #selectNow(Consumer)} methods, and involves three steps:  </p>
       *
       * <ol>
       *
       *   <li><p> Each key in the cancelled-key set is removed from each key set of
       *   which it is a member, and its channel is deregistered.  This step leaves
       *   the cancelled-key set empty. </p></li>
       *
       *   <li><p> The underlying operating system is queried for an update as to the
       *   readiness of each remaining channel to perform any of the operations
       *   identified by its key's interest set as of the moment that the selection
       *   operation began.
       *
       *   <p> For a channel that is ready for at least one such operation, the
       *   ready-operation set of the channel's key is set to identify exactly the
       *   operations for which the channel is ready and the <i>action</i> method
       *   specified to the {@code select} method is invoked to consume the channel's
       *   key. Any readiness information previously recorded in the ready set is
       *   discarded prior to invoking the <i>action</i> method.
       *
       *   <p> Alternatively, where a channel is ready for more than one operation,
       *   its <i>action</i> method may be invoked more than once with the channel's
       *   key and ready-operation set modified to a subset of the operations for
       *   which the channel is ready.  Where the <i>action</i> method is invoked more
       *   than once for the same key then its ready-operation set never contains
       *   operation bits that were contained in the set at previous calls to the
       *   <i>action</i> method in the same selection operation.  </p></li>
       *
       *   <li><p> If any keys were added to the cancelled-key set while step (2) was
       *   in progress then they are processed as in step (1). </p></li>
       *
       * </ol>
       */
      
      /**
       * Selects and performs an action on the keys whose corresponding channels
       * are ready for I/O operations.
       *
       * <p> This method performs a blocking <a href="#selop">selection
       * operation</a>.  It wakes up from querying the operating system only when
       * at least one channel is selected, this selector's {@link #wakeup wakeup}
       * method is invoked, the current thread is interrupted, or the given
       * timeout period expires, whichever comes first.
       *
       * <p> The specified <i>action</i> is invoked with the key for each channel
       * that is ready to perform an operation identified by its key's interest
       * set.  The <i>action</i> method may be invoked more than once for the same
       * key but with the ready-operation set containing a subset of the operations
       * for which the channel is ready (as described above).
       *
       * The <i>action</i> method is invoked while synchronized on the selector
       * and its selected-key set.  Great care must be taken to avoid deadlocking
       * with other threads that also synchronize on these objects.
       * Selection operations are not reentrant in general and consequently the
       * <i>action</i> should take great care not to attempt a selection operation
       * on the same selector.  The behavior when attempting a reentrant selection
       * operation is implementation specific and therefore not specified.  If the
       * <i>action</i> method closes the selector then {@code ClosedSelectorException}
       * is thrown when the action completes.  The <i>action</i> method is not
       * prohibited from closing channels registered with the selector, nor
       * prohibited from cancelling keys or changing a key's interest set.  If a
       * channel is selected but its key is cancelled or its interest set changed
       * before the <i>action</i> is performed on the key then it is
       * implementation specific as to whether the action <i>action</i> is invoked
       * (it may be invoked with an {@link SelectionKey#isValid() invalid} key).
       * Exceptions thrown by the action are relayed to the caller.
       *
       * <p> This method does not offer real-time guarantees: It schedules the
       * timeout as if by invoking the {@link Object#wait(long)} method.
       *
       * @implSpec The default implementation removes all keys from the
       * selected-key set, invokes {@link #select(long) select(long)} with the
       * given timeout and then performs the action for each key added to the
       * selected-key set.  The default implementation does not detect the action
       * performing a reentrant selection operation.  The selected-key set may
       * or may not be empty on completion of the default implementation.
       *
       * @param  action   The action to perform
       *
       * @param  timeout  If positive, block for up to {@code timeout}
       *                  milliseconds, more or less, while waiting for a
       *                  channel to become ready; if zero, block indefinitely;
       *                  must not be negative
       *
       * @return  The number of unique keys consumed, possibly zero
       *
       * @throws  IOException
       *          If an I/O error occurs
       *
       * @throws  ClosedSelectorException
       *          If this selector is closed or is closed by the action
       *
       * @throws  IllegalArgumentException
       *          If the value of the timeout argument is negative
       *
       * @since 11
       */
      public int select(Consumer<SelectionKey> action, long timeout)
          throws IOException
      
      /**
       * Selects and performs an action on the keys whose corresponding channels
       * are ready for I/O operations.
       *
       * <p> This method performs a blocking <a href="#selop">selection
       * operation</a>.  It wakes up from querying the operating system only when
       * at least one channel is selected, this selector's {@link #wakeup wakeup}
       * method is invoked, or the current thread is interrupted, whichever comes
       * first.
       *
       * <p> This method is equivalent to invoking the 2-arg
       * {@link #select(Consumer, long) select} method with a timeout of {@code 0}
       * to block indefinitely.  </p>
       *
       * @implSpec The default implementation invokes the 2-arg {@code select}
       * method with a timeout of {@code 0}.
       *
       * @param  action   The action to perform
       *
       * @return  The number of unique keys consumed, possibly zero
       *
       * @throws  IOException
       *          If an I/O error occurs
       *
       * @throws  ClosedSelectorException
       *          If this selector is closed or is closed by the action
       *
       * @since 11
       */
      public int select(Consumer<SelectionKey> action) throws IOException
      
      /**
       * Selects and performs an action on the keys whose corresponding channels
       * are ready for I/O operations.
       *
       * <p> This method performs a non-blocking <a href="#selop">selection
       * operation</a>.
       *
       * <p> Invoking this method clears the effect of any previous invocations
       * of the {@link #wakeup wakeup} method.  </p>
       *
       * @implSpec The default implementation removes all keys from the
       * selected-key set, invokes {@link #selectNow() selectNow()} and then
       * performs the action for each key added to the selected-key set.  The
       * default implementation does not detect the action performing a reentrant
       * selection operation.  The selected-key set may or may not be empty on
       * completion of the default implementation.
       *
       * @param  action   The action to perform
       *
       * @return  The number of unique keys consumed, possibly zero
       *
       * @throws  IOException
       *          If an I/O error occurs
       *
       * @throws  ClosedSelectorException
       *          If this selector is closed or is closed by the action
       *
       * @since 11
       */
      public int selectNow(Consumer<SelectionKey> action)
          throws IOException

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                alanb Alan Bateman
                Reporter:
                alanb Alan Bateman
                Reviewed By:
                Brian Burkhalter
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: