⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractselectablechannel.java

📁 java1.6众多例子参考
💻 JAVA
字号:
/* * @(#)AbstractSelectableChannel.java	1.26 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.*;/** * Base implementation class for selectable channels. * * <p> This class defines methods that handle the mechanics of channel * registration, deregistration, and closing.  It maintains the current * blocking mode of this channel as well as its current set of selection keys. * It performs all of the synchronization required to implement the {@link * java.nio.channels.SelectableChannel} specification.  Implementations of the * abstract protected methods defined in this class need not synchronize * against other threads that might be engaged in the same operations.  </p> * * * @author Mark Reinhold * @author Mike McCloskey * @author JSR-51 Expert Group * @version 1.26, 05/11/17 * @since 1.4 */public abstract class AbstractSelectableChannel    extends SelectableChannel{    // The provider that created this channel    private final SelectorProvider provider;    // Keys that have been created by registering this channel with selectors.    // They are saved because if this channel is closed the keys must be    // deregistered.  Protected by keyLock.    //    private SelectionKey[] keys = null;    private int keyCount = 0;    // Lock for key set and count    private final Object keyLock = new Object();    // Lock for registration and configureBlocking operations    private final Object regLock = new Object();    // Blocking mode, protected by regLock    boolean blocking = true;    /**     * Initializes a new instance of this class.     */    protected AbstractSelectableChannel(SelectorProvider provider) {	this.provider = provider;    }    /**     * Returns the provider that created this channel.     *     * @return  The provider that created this channel     */    public final SelectorProvider provider() {	return provider;    }    // -- Utility methods for the key set --    private void addKey(SelectionKey k) {	synchronized (keyLock) {	    int i = 0;	    if ((keys != null) && (keyCount < keys.length)) {		// Find empty element of key array		for (i = 0; i < keys.length; i++)		    if (keys[i] == null)			break;	    } else if (keys == null) {                keys =  new SelectionKey[3];            } else {		// Grow key array		int n = keys.length * 2;		SelectionKey[] ks =  new SelectionKey[n];		for (i = 0; i < keys.length; i++)		    ks[i] = keys[i];		keys = ks;		i = keyCount;	    }	    keys[i] = k;	    keyCount++;	}    }    private SelectionKey findKey(Selector sel) {	synchronized (keyLock) {            if (keys == null)                return null;	    for (int i = 0; i < keys.length; i++)                if ((keys[i] != null) && (keys[i].selector() == sel))                    return keys[i];	    return null;	}    }    void removeKey(SelectionKey k) {			// package-private	synchronized (keyLock) {	    for (int i = 0; i < keys.length; i++)		if (keys[i] == k) {		    keys[i] = null;		    keyCount--;		}	    ((AbstractSelectionKey)k).invalidate();	}    }    private boolean haveValidKeys() {	synchronized (keyLock) {	    if (keyCount == 0)		return false;	    for (int i = 0; i < keys.length; i++) {		if ((keys[i] != null) && keys[i].isValid())		    return true;	    }	    return false;	}    }    // -- Registration --    public final boolean isRegistered() {	synchronized (keyLock) {	    return keyCount != 0;	}    }    public final SelectionKey keyFor(Selector sel) {	return findKey(sel);    }    /**     * Registers this channel with the given selector, returning a selection key.     *     * <p>  This method first verifies that this channel is open and that the     * given initial interest set is valid.     *     * <p> If this channel is already registered with the given selector then     * the selection key representing that registration is returned after     * setting its interest set to the given value.     *     * <p> Otherwise this channel has not yet been registered with the given     * selector, so the {@link AbstractSelector#register register} method of     * the selector is invoked while holding the appropriate locks.  The     * resulting key is added to this channel's key set before being returned.     * </p>     */    public final SelectionKey register(Selector sel, int ops,				       Object att)	throws ClosedChannelException    {	if (!isOpen())	    throw new ClosedChannelException();	if ((ops & ~validOps()) != 0)	    throw new IllegalArgumentException();	synchronized (regLock) {	    if (blocking)		throw new IllegalBlockingModeException();	    SelectionKey k = findKey(sel);            if (k != null) {                k.interestOps(ops);		k.attach(att);            }	    if (k == null) {		// New registration		k = ((AbstractSelector)sel).register(this, ops, att);		addKey(k);	    }            return k;        }    }    // -- Closing --    /**     * Closes this channel.     *     * <p> This method, which is specified in the {@link     * AbstractInterruptibleChannel} class and is invoked by the {@link     * java.nio.channels.Channel#close close} method, in turn invokes the     * {@link #implCloseSelectableChannel implCloseSelectableChannel} method in     * order to perform the actual work of closing this channel.  It then     * cancels all of this channel's keys.  </p>     */    protected final void implCloseChannel() throws IOException {	implCloseSelectableChannel();	synchronized (keyLock) {            int count = (keys == null) ? 0 : keys.length;	    for (int i = 0; i < count; i++) {		SelectionKey k = keys[i];		if (k != null)		    k.cancel();	    }	}    }    /**     * Closes this selectable channel.     *     * <p> This method is invoked by the {@link java.nio.channels.Channel#close     * close} method in order to perform the actual work of closing the     * channel.  This method is only invoked if the channel 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 an I/O operation upon this channel to return     * immediately, either by throwing an exception or by returning normally.     * </p>     */    protected abstract void implCloseSelectableChannel() throws IOException;    // -- Blocking --    public final boolean isBlocking() {	synchronized (regLock) {	    return blocking;	}    }    public final Object blockingLock() {	return regLock;    }    /**     * Adjusts this channel's blocking mode.     *     * <p> If the given blocking mode is different from the current blocking     * mode then this method invokes the {@link #implConfigureBlocking     * implConfigureBlocking} method, while holding the appropriate locks, in     * order to change the mode.  </p>     */    public final SelectableChannel configureBlocking(boolean block)	throws IOException    {        if (!isOpen())            throw new ClosedChannelException();	synchronized (regLock) {	    if (blocking == block)		return this;	    if (block && haveValidKeys())		throw new IllegalBlockingModeException();	    implConfigureBlocking(block);	    blocking = block;	}	return this;    }    /**     * Adjusts this channel's blocking mode.     *     * <p> This method is invoked by the {@link #configureBlocking     * configureBlocking} method in order to perform the actual work of     * changing the blocking mode.  This method is only invoked if the new mode     * is different from the current mode.  </p>     *     * @throws IOException     *         If an I/O error occurs     */    protected abstract void implConfigureBlocking(boolean block)	throws IOException;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -