Path: blob/master/src/java.base/share/classes/java/nio/channels/Selector.java
41159 views
/*1* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.nio.channels;2627import java.io.Closeable;28import java.io.IOException;29import java.nio.channels.spi.SelectorProvider;30import java.util.Objects;31import java.util.Set;32import java.util.function.Consumer;333435/**36* A multiplexor of {@link SelectableChannel} objects.37*38* <p> A selector may be created by invoking the {@link #open open} method of39* this class, which will use the system's default {@link40* java.nio.channels.spi.SelectorProvider selector provider} to41* create a new selector. A selector may also be created by invoking the42* {@link java.nio.channels.spi.SelectorProvider#openSelector openSelector}43* method of a custom selector provider. A selector remains open until it is44* closed via its {@link #close close} method.45*46* <a id="ks"></a>47*48* <p> A selectable channel's registration with a selector is represented by a49* {@link SelectionKey} object. A selector maintains three sets of selection50* keys:51*52* <ul>53*54* <li><p> The <i>key set</i> contains the keys representing the current55* channel registrations of this selector. This set is returned by the56* {@link #keys() keys} method. </p></li>57*58* <li><p> The <i>selected-key set</i> is the set of keys such that each59* key's channel was detected to be ready for at least one of the operations60* identified in the key's interest set during a prior selection operation61* that adds keys or updates keys in the set.62* This set is returned by the {@link #selectedKeys() selectedKeys} method.63* The selected-key set is always a subset of the key set. </p></li>64*65* <li><p> The <i>cancelled-key</i> set is the set of keys that have been66* cancelled but whose channels have not yet been deregistered. This set is67* not directly accessible. The cancelled-key set is always a subset of the68* key set. </p></li>69*70* </ul>71*72* <p> All three sets are empty in a newly-created selector.73*74* <p> A key is added to a selector's key set as a side effect of registering a75* channel via the channel's {@link SelectableChannel#register(Selector,int)76* register} method. Cancelled keys are removed from the key set during77* selection operations. The key set itself is not directly modifiable.78*79* <p> A key is added to its selector's cancelled-key set when it is cancelled,80* whether by closing its channel or by invoking its {@link SelectionKey#cancel81* cancel} method. Cancelling a key will cause its channel to be deregistered82* during the next selection operation, at which time the key will be removed83* from all of the selector's key sets.84*85* <a id="sks"></a><p> Keys are added to the selected-key set by selection86* operations. A key may be removed directly from the selected-key set by87* invoking the set's {@link java.util.Set#remove(java.lang.Object) remove}88* method or by invoking the {@link java.util.Iterator#remove() remove} method89* of an {@link java.util.Iterator iterator} obtained from the set.90* All keys may be removed from the selected-key set by invoking the set's91* {@link java.util.Set#clear() clear} method. Keys may not be added directly92* to the selected-key set. </p>93*94* <a id="selop"></a>95* <h2>Selection</h2>96*97* <p> A selection operation queries the underlying operating system for an98* update as to the readiness of each registered channel to perform any of the99* operations identified by its key's interest set. There are two forms of100* selection operation:101*102* <ol>103*104* <li><p> The {@link #select()}, {@link #select(long)}, and {@link #selectNow()}105* methods add the keys of channels ready to perform an operation to the106* selected-key set, or update the ready-operation set of keys already in the107* selected-key set. </p></li>108*109* <li><p> The {@link #select(Consumer)}, {@link #select(Consumer, long)}, and110* {@link #selectNow(Consumer)} methods perform an <i>action</i> on the key111* of each channel that is ready to perform an operation. These methods do112* not add to the selected-key set. </p></li>113*114* </ol>115*116* <h3>Selection operations that add to the selected-key set</h3>117*118* <p> During each selection operation, keys may be added to and removed from a119* selector's selected-key set and may be removed from its key and120* cancelled-key sets. Selection is performed by the {@link #select()}, {@link121* #select(long)}, and {@link #selectNow()} methods, and involves three steps:122* </p>123*124* <ol>125*126* <li><p> Each key in the cancelled-key set is removed from each key set of127* which it is a member, and its channel is deregistered. This step leaves128* the cancelled-key set empty. </p></li>129*130* <li><p> The underlying operating system is queried for an update as to the131* readiness of each remaining channel to perform any of the operations132* identified by its key's interest set as of the moment that the selection133* operation began. For a channel that is ready for at least one such134* operation, one of the following two actions is performed: </p>135*136* <ol>137*138* <li><p> If the channel's key is not already in the selected-key set then139* it is added to that set and its ready-operation set is modified to140* identify exactly those operations for which the channel is now reported141* to be ready. Any readiness information previously recorded in the ready142* set is discarded. </p></li>143*144* <li><p> Otherwise the channel's key is already in the selected-key set,145* so its ready-operation set is modified to identify any new operations146* for which the channel is reported to be ready. Any readiness147* information previously recorded in the ready set is preserved; in other148* words, the ready set returned by the underlying system is149* bitwise-disjoined into the key's current ready set. </p></li>150*151* </ol>152*153* If all of the keys in the key set at the start of this step have empty154* interest sets then neither the selected-key set nor any of the keys'155* ready-operation sets will be updated.156*157* <li><p> If any keys were added to the cancelled-key set while step (2) was158* in progress then they are processed as in step (1). </p></li>159*160* </ol>161*162* <p> Whether or not a selection operation blocks to wait for one or more163* channels to become ready, and if so for how long, is the only essential164* difference between the three selection methods. </p>165*166*167* <h3>Selection operations that perform an action on selected keys</h3>168*169* <p> During each selection operation, keys may be removed from the selector's170* key, selected-key, and cancelled-key sets. Selection is performed by the171* {@link #select(Consumer)}, {@link #select(Consumer,long)}, and {@link172* #selectNow(Consumer)} methods, and involves three steps: </p>173*174* <ol>175*176* <li><p> Each key in the cancelled-key set is removed from each key set of177* which it is a member, and its channel is deregistered. This step leaves178* the cancelled-key set empty. </p></li>179*180* <li><p> The underlying operating system is queried for an update as to the181* readiness of each remaining channel to perform any of the operations182* identified by its key's interest set as of the moment that the selection183* operation began.184*185* <p> For a channel that is ready for at least one such operation, the186* ready-operation set of the channel's key is set to identify exactly the187* operations for which the channel is ready and the <i>action</i> specified188* to the {@code select} method is invoked to consume the channel's key. Any189* readiness information previously recorded in the ready set is discarded190* prior to invoking the <i>action</i>.191*192* <p> Alternatively, where a channel is ready for more than one operation,193* the <i>action</i> may be invoked more than once with the channel's key and194* ready-operation set modified to a subset of the operations for which the195* channel is ready. Where the <i>action</i> is invoked more than once for196* the same key then its ready-operation set never contains operation bits197* that were contained in the set at previous calls to the <i>action</i>198* in the same selection operation. </p></li>199*200* <li><p> If any keys were added to the cancelled-key set while step (2) was201* in progress then they are processed as in step (1). </p></li>202*203* </ol>204*205*206* <h2>Concurrency</h2>207*208* <p> A Selector and its key set are safe for use by multiple concurrent209* threads. Its selected-key set and cancelled-key set, however, are not.210*211* <p> The selection operations synchronize on the selector itself, on the212* selected-key set, in that order. They also synchronize on the cancelled-key213* set during steps (1) and (3) above.214*215* <p> Changes made to the interest sets of a selector's keys while a216* selection operation is in progress have no effect upon that operation; they217* will be seen by the next selection operation.218*219* <p> Keys may be cancelled and channels may be closed at any time. Hence the220* presence of a key in one or more of a selector's key sets does not imply221* that the key is valid or that its channel is open. Application code should222* be careful to synchronize and check these conditions as necessary if there223* is any possibility that another thread will cancel a key or close a channel.224*225* <p> A thread blocked in a selection operation may be interrupted by some226* other thread in one of three ways:227*228* <ul>229*230* <li><p> By invoking the selector's {@link #wakeup wakeup} method,231* </p></li>232*233* <li><p> By invoking the selector's {@link #close close} method, or234* </p></li>235*236* <li><p> By invoking the blocked thread's {@link237* java.lang.Thread#interrupt() interrupt} method, in which case its238* interrupt status will be set and the selector's {@link #wakeup wakeup}239* method will be invoked. </p></li>240*241* </ul>242*243* <p> The {@link #close close} method synchronizes on the selector and its244* selected-key set in the same order as in a selection operation.245*246* <a id="ksc"></a>247* <p> A Selector's key set is safe for use by multiple concurrent threads.248* Retrieval operations from the key set do not generally block and so may249* overlap with new registrations that add to the set, or with the cancellation250* steps of selection operations that remove keys from the set. Iterators and251* spliterators return elements reflecting the state of the set at some point at252* or since the creation of the iterator/spliterator. They do not throw253* {@link java.util.ConcurrentModificationException ConcurrentModificationException}.254*255* <a id="sksc"></a>256* <p> A selector's selected-key set is not, in general, safe for use by257* multiple concurrent threads. If such a thread might modify the set directly258* then access should be controlled by synchronizing on the set itself. The259* iterators returned by the set's {@link java.util.Set#iterator() iterator}260* methods are <i>fail-fast:</i> If the set is modified after the iterator is261* created, in any way except by invoking the iterator's own {@link262* java.util.Iterator#remove() remove} method, then a {@link263* java.util.ConcurrentModificationException} will be thrown. </p>264*265* @author Mark Reinhold266* @author JSR-51 Expert Group267* @since 1.4268*269* @see SelectableChannel270* @see SelectionKey271*/272273public abstract class Selector implements Closeable {274275/**276* Initializes a new instance of this class.277*/278protected Selector() { }279280/**281* Opens a selector.282*283* <p> The new selector is created by invoking the {@link284* java.nio.channels.spi.SelectorProvider#openSelector openSelector} method285* of the system-wide default {@link286* java.nio.channels.spi.SelectorProvider} object. </p>287*288* @return A new selector289*290* @throws IOException291* If an I/O error occurs292*/293public static Selector open() throws IOException {294return SelectorProvider.provider().openSelector();295}296297/**298* Tells whether or not this selector is open.299*300* @return {@code true} if, and only if, this selector is open301*/302public abstract boolean isOpen();303304/**305* Returns the provider that created this channel.306*307* @return The provider that created this channel308*/309public abstract SelectorProvider provider();310311/**312* Returns this selector's key set.313*314* <p> The key set is not directly modifiable. A key is removed only after315* it has been cancelled and its channel has been deregistered. Any316* attempt to modify the key set will cause an {@link317* UnsupportedOperationException} to be thrown.318*319* <p> The set is <a href="#ksc">safe</a> for use by multiple concurrent320* threads. </p>321*322* @return This selector's key set323*324* @throws ClosedSelectorException325* If this selector is closed326*/327public abstract Set<SelectionKey> keys();328329/**330* Returns this selector's selected-key set.331*332* <p> Keys may be removed from, but not directly added to, the333* selected-key set. Any attempt to add an object to the key set will334* cause an {@link UnsupportedOperationException} to be thrown.335*336* <p> The selected-key set is <a href="#sksc">not thread-safe</a>. </p>337*338* @return This selector's selected-key set339*340* @throws ClosedSelectorException341* If this selector is closed342*/343public abstract Set<SelectionKey> selectedKeys();344345/**346* Selects a set of keys whose corresponding channels are ready for I/O347* operations.348*349* <p> This method performs a non-blocking <a href="#selop">selection350* operation</a>. If no channels have become selectable since the previous351* selection operation then this method immediately returns zero.352*353* <p> Invoking this method clears the effect of any previous invocations354* of the {@link #wakeup wakeup} method. </p>355*356* @return The number of keys, possibly zero, whose ready-operation sets357* were updated by the selection operation358*359* @throws IOException360* If an I/O error occurs361*362* @throws ClosedSelectorException363* If this selector is closed364*/365public abstract int selectNow() throws IOException;366367/**368* Selects a set of keys whose corresponding channels are ready for I/O369* operations.370*371* <p> This method performs a blocking <a href="#selop">selection372* operation</a>. It returns only after at least one channel is selected,373* this selector's {@link #wakeup wakeup} method is invoked, the current374* thread is interrupted, or the given timeout period expires, whichever375* comes first.376*377* <p> This method does not offer real-time guarantees: It schedules the378* timeout as if by invoking the {@link Object#wait(long)} method. </p>379*380* @param timeout If positive, block for up to {@code timeout}381* milliseconds, more or less, while waiting for a382* channel to become ready; if zero, block indefinitely;383* must not be negative384*385* @return The number of keys, possibly zero,386* whose ready-operation sets were updated387*388* @throws IOException389* If an I/O error occurs390*391* @throws ClosedSelectorException392* If this selector is closed393*394* @throws IllegalArgumentException395* If the value of the timeout argument is negative396*/397public abstract int select(long timeout) throws IOException;398399/**400* Selects a set of keys whose corresponding channels are ready for I/O401* operations.402*403* <p> This method performs a blocking <a href="#selop">selection404* operation</a>. It returns only after at least one channel is selected,405* this selector's {@link #wakeup wakeup} method is invoked, or the current406* thread is interrupted, whichever comes first. </p>407*408* @return The number of keys, possibly zero,409* whose ready-operation sets were updated410*411* @throws IOException412* If an I/O error occurs413*414* @throws ClosedSelectorException415* If this selector is closed416*/417public abstract int select() throws IOException;418419/**420* Selects and performs an action on the keys whose corresponding channels421* are ready for I/O operations.422*423* <p> This method performs a blocking <a href="#selop">selection424* operation</a>. It wakes up from querying the operating system only when425* at least one channel is selected, this selector's {@link #wakeup wakeup}426* method is invoked, the current thread is interrupted, or the given427* timeout period expires, whichever comes first.428*429* <p> The specified <i>action</i>'s {@link Consumer#accept(Object) accept}430* method is invoked with the key for each channel that is ready to perform431* an operation identified by its key's interest set. The {@code accept}432* method may be invoked more than once for the same key but with the433* ready-operation set containing a subset of the operations for which the434* channel is ready (as described above). The {@code accept} method is435* invoked while synchronized on the selector and its selected-key set.436* Great care must be taken to avoid deadlocking with other threads that437* also synchronize on these objects. Selection operations are not reentrant438* in general and consequently the <i>action</i> should take great care not439* to attempt a selection operation on the same selector. The behavior when440* attempting a reentrant selection operation is implementation specific and441* therefore not specified. If the <i>action</i> closes the selector then442* {@code ClosedSelectorException} is thrown when the action completes.443* The <i>action</i> is not prohibited from closing channels registered with444* the selector, nor prohibited from cancelling keys or changing a key's445* interest set. If a channel is selected but its key is cancelled or its446* interest set changed before the <i>action</i> is performed on the key447* then it is implementation specific as to whether the <i>action</i> is448* invoked (it may be invoked with an {@link SelectionKey#isValid() invalid}449* key). Exceptions thrown by the action are relayed to the caller.450*451* <p> This method does not offer real-time guarantees: It schedules the452* timeout as if by invoking the {@link Object#wait(long)} method.453*454* @implSpec The default implementation removes all keys from the455* selected-key set, invokes {@link #select(long) select(long)} with the456* given timeout and then performs the action for each key added to the457* selected-key set. The default implementation does not detect the action458* performing a reentrant selection operation. The selected-key set may459* or may not be empty on completion of the default implementation.460*461* @param action The action to perform462*463* @param timeout If positive, block for up to {@code timeout}464* milliseconds, more or less, while waiting for a465* channel to become ready; if zero, block indefinitely;466* must not be negative467*468* @return The number of unique keys consumed, possibly zero469*470* @throws IOException471* If an I/O error occurs472*473* @throws ClosedSelectorException474* If this selector is closed or is closed by the action475*476* @throws IllegalArgumentException477* If the value of the timeout argument is negative478*479* @since 11480*/481public int select(Consumer<SelectionKey> action, long timeout)482throws IOException483{484if (timeout < 0)485throw new IllegalArgumentException("Negative timeout");486return doSelect(Objects.requireNonNull(action), timeout);487}488489/**490* Selects and performs an action on the keys whose corresponding channels491* are ready for I/O operations.492*493* <p> This method performs a blocking <a href="#selop">selection494* operation</a>. It wakes up from querying the operating system only when495* at least one channel is selected, this selector's {@link #wakeup wakeup}496* method is invoked, or the current thread is interrupted, whichever comes497* first.498*499* <p> This method is equivalent to invoking the 2-arg500* {@link #select(Consumer, long) select} method with a timeout of {@code 0}501* to block indefinitely. </p>502*503* @implSpec The default implementation invokes the 2-arg {@code select}504* method with a timeout of {@code 0}.505*506* @param action The action to perform507*508* @return The number of unique keys consumed, possibly zero509*510* @throws IOException511* If an I/O error occurs512*513* @throws ClosedSelectorException514* If this selector is closed or is closed by the action515*516* @since 11517*/518public int select(Consumer<SelectionKey> action) throws IOException {519return select(action, 0);520}521522/**523* Selects and performs an action on the keys whose corresponding channels524* are ready for I/O operations.525*526* <p> This method performs a non-blocking <a href="#selop">selection527* operation</a>.528*529* <p> Invoking this method clears the effect of any previous invocations530* of the {@link #wakeup wakeup} method. </p>531*532* @implSpec The default implementation removes all keys from the533* selected-key set, invokes {@link #selectNow() selectNow()} and then534* performs the action for each key added to the selected-key set. The535* default implementation does not detect the action performing a reentrant536* selection operation. The selected-key set may or may not be empty on537* completion of the default implementation.538*539* @param action The action to perform540*541* @return The number of unique keys consumed, possibly zero542*543* @throws IOException544* If an I/O error occurs545*546* @throws ClosedSelectorException547* If this selector is closed or is closed by the action548*549* @since 11550*/551public int selectNow(Consumer<SelectionKey> action) throws IOException {552return doSelect(Objects.requireNonNull(action), -1);553}554555/**556* Default implementation of select(Consumer) and selectNow(Consumer).557*/558private int doSelect(Consumer<SelectionKey> action, long timeout)559throws IOException560{561synchronized (this) {562Set<SelectionKey> selectedKeys = selectedKeys();563synchronized (selectedKeys) {564selectedKeys.clear();565int numKeySelected;566if (timeout < 0) {567numKeySelected = selectNow();568} else {569numKeySelected = select(timeout);570}571572// copy selected-key set as action may remove keys573Set<SelectionKey> keysToConsume = Set.copyOf(selectedKeys);574assert keysToConsume.size() == numKeySelected;575selectedKeys.clear();576577// invoke action for each selected key578keysToConsume.forEach(k -> {579action.accept(k);580if (!isOpen())581throw new ClosedSelectorException();582});583584return numKeySelected;585}586}587}588589590/**591* Causes the first selection operation that has not yet returned to return592* immediately.593*594* <p> If another thread is currently blocked in a selection operation then595* that invocation will return immediately. If no selection operation is596* currently in progress then the next invocation of a selection operation597* will return immediately unless {@link #selectNow()} or {@link598* #selectNow(Consumer)} is invoked in the meantime. In any case the value599* returned by that invocation may be non-zero. Subsequent selection600* operations will block as usual unless this method is invoked again in the601* meantime.602*603* <p> Invoking this method more than once between two successive selection604* operations has the same effect as invoking it just once. </p>605*606* @return This selector607*/608public abstract Selector wakeup();609610/**611* Closes this selector.612*613* <p> If a thread is currently blocked in one of this selector's selection614* methods then it is interrupted as if by invoking the selector's {@link615* #wakeup wakeup} method.616*617* <p> Any uncancelled keys still associated with this selector are618* invalidated, their channels are deregistered, and any other resources619* associated with this selector are released.620*621* <p> If this selector is already closed then invoking this method has no622* effect.623*624* <p> After a selector is closed, any further attempt to use it, except by625* invoking this method or the {@link #wakeup wakeup} method, will cause a626* {@link ClosedSelectorException} to be thrown. </p>627*628* @throws IOException629* If an I/O error occurs630*/631public abstract void close() throws IOException;632}633634635