📄 abstractselector.java
字号:
/* * @(#)AbstractSelector.java 1.21 05/11/17 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package java.nio.channels.spi;import java.io.IOException;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.util.HashSet;import java.util.Set;import sun.nio.ch.Interruptible;import java.util.concurrent.atomic.AtomicBoolean;/** * Base implementation class for selectors. * * <p> This class encapsulates the low-level machinery required to implement * the interruption of selection operations. A concrete selector class must * invoke the {@link #begin begin} and {@link #end end} methods before and * after, respectively, invoking an I/O operation that might block * indefinitely. In order to ensure that the {@link #end end} method is always * invoked, these methods should be used within a * <tt>try</tt> ... <tt>finally</tt> block: <a name="be"> * * <blockquote><pre> * try { * begin(); * // Perform blocking I/O operation here * ... * } finally { * end(); * }</pre></blockquote> * * <p> This class also defines methods for maintaining a selector's * cancelled-key set and for removing a key from its channel's key set, and * declares the abstract {@link #register register} method that is invoked by a * selectable channel's {@link AbstractSelectableChannel#register register} * method in order to perform the actual work of registering a channel. </p> * * * @author Mark Reinhold * @author JSR-51 Expert Group * @version 1.21, 05/11/17 * @since 1.4 */public abstract class AbstractSelector extends Selector{ private AtomicBoolean selectorOpen = new AtomicBoolean(true); // The provider that created this selector private final SelectorProvider provider; /** * Initializes a new instance of this class. </p> */ protected AbstractSelector(SelectorProvider provider) { this.provider = provider; } private final Set cancelledKeys = new HashSet(); void cancel(SelectionKey k) { // package-private synchronized (cancelledKeys) { cancelledKeys.add(k); } } /** * Closes this selector. * * <p> If the selector has already been closed then this method returns * immediately. Otherwise it marks the selector as closed and then invokes * the {@link #implCloseSelector implCloseSelector} method in order to * complete the close operation. </p> * * @throws IOException * If an I/O error occurs */ public final void close() throws IOException { boolean open = selectorOpen.getAndSet(false); if (!open) return; implCloseSelector(); } /** * Closes this selector. * * <p> This method is invoked by the {@link #close close} method in order * to perform the actual work of closing the selector. This method is only * invoked if the selector has not yet been closed, and it is never invoked * more than once. * * <p> An implementation of this method must arrange for any other thread * that is blocked in a selection operation upon this selector to return * immediately as if by invoking the {@link * java.nio.channels.Selector#wakeup wakeup} method. </p> * * @throws IOException * If an I/O error occurs while closing the selector */ protected abstract void implCloseSelector() throws IOException; public final boolean isOpen() { return selectorOpen.get(); } /** * Returns the provider that created this channel. * * @return The provider that created this channel */ public final SelectorProvider provider() { return provider; } /** * Retrieves this selector's cancelled-key set. * * <p> This set should only be used while synchronized upon it. </p> * * @return The cancelled-key set */ protected final Set<SelectionKey> cancelledKeys() { return cancelledKeys; } /** * Registers the given channel with this selector. * * <p> This method is invoked by a channel's {@link * AbstractSelectableChannel#register register} method in order to perform * the actual work of registering the channel with this selector. </p> * * @param ch * The channel to be registered * * @param ops * The initial interest set, which must be valid * * @param att * The initial attachment for the resulting key * * @return A new key representing the registration of the given channel * with this selector */ protected abstract SelectionKey register(AbstractSelectableChannel ch, int ops, Object att); /** * Removes the given key from its channel's key set. * * <p> This method must be invoked by the selector for each channel that it * deregisters. </p> * * @param key * The selection key to be removed */ protected final void deregister(AbstractSelectionKey key) { ((AbstractSelectableChannel)key.channel()).removeKey(key); } // -- Interruption machinery -- private Interruptible interruptor = null; /** * Marks the beginning of an I/O operation that might block indefinitely. * * <p> This method should be invoked in tandem with the {@link #end end} * method, using a <tt>try</tt> ... <tt>finally</tt> block as * shown <a href="#be">above</a>, in order to implement interruption for * this selector. * * <p> Invoking this method arranges for the selector's {@link * Selector#wakeup wakeup} method to be invoked if a thread's {@link * Thread#interrupt interrupt} method is invoked while the thread is * blocked in an I/O operation upon the selector. </p> */ protected final void begin() { if (interruptor == null) { interruptor = new Interruptible() { public void interrupt() { AbstractSelector.this.wakeup(); }}; } AbstractInterruptibleChannel.blockedOn(interruptor); if (Thread.currentThread().isInterrupted()) interruptor.interrupt(); } /** * Marks the end of an I/O operation that might block indefinitely. * * <p> This method should be invoked in tandem with the {@link #begin begin} * method, using a <tt>try</tt> ... <tt>finally</tt> block as * shown <a href="#be">above</a>, in order to implement interruption for * this selector. </p> */ protected final void end() { AbstractInterruptibleChannel.blockedOn(null); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -