SelectableChannel接口定义

Channel接口定义:[url]http://donald-draper.iteye.com/blog/2369111[/url]
AbstractInterruptibleChannel接口定义:[url]http://donald-draper.iteye.com/blog/2369238[/url]
上一篇文章我们讲到可以异步中断和关闭通道接口的定义。先来回顾一下:
AbstractInterruptibleChannel是一个可以异步关闭和中断IO阻塞线程的通道,所有具体的通道实现,如果想要可以异步关闭和中断,必须实现此类。AbstractInterruptibleChannel内部有一个Open布尔值用于表示通道是否打开。在通道关闭时调用implCloseChannel方法完成
实际的关闭通道工作。有个中断处理器用于记录中断阻塞IO操作线程的线程,完成实际的关闭通道工作。有一组协调方法为begin和end方法,一般在一个可能阻塞的IO操作的开始调用begin,之后调用end方法,这些操作一般用一个try语句块,组合使用。begin方法主要初始化中断处理器,end方法根据IO操作是否完成和Open状态,及中断线程处理器,中断线程判断是抛出AsynchronousCloseException异常还是ClosedByInterruptException。
ServerSocketChannel父类结构树:
//ServerSocketChannel
public abstract class ServerSocketChannel
extends AbstractSelectableChannel
implements NetworkChannel

//AbstractSelectableChannel
public abstract class AbstractSelectableChannel
extends SelectableChannel

//SelectableChannel
public abstract class SelectableChannel
extends AbstractInterruptibleChannel
implements Channel

今天我们来看一下可选择通道SelectableChannel的定义:
package java.nio.channels;

import java.io.IOException;
import java.nio.channels.spi.AbstractInterruptibleChannel;
import java.nio.channels.spi.SelectorProvider;


/**
* A channel that can be multiplexed via a {@link Selector}.
*
SelectableChannel是可以通过选择器多路复用的通道。
* In order to be used with a selector, an instance of this class must
* first be <i>registered</i> via the {@link #register(Selector,int,Object)
* register} method. This method returns a new {@link SelectionKey} object
* that represents the channel's registration with the selector.
*
如果想要被选择器selector使用,通道的实体类必须先通道register(Selector,int,Object)
方法,将通道关注的事件SelectionKey和Attaching的Object注册到选择器中。注册方法返回一个
SelectionKey对象,表示通道注册到选择器中的注册器。
* Once registered with a selector, a channel remains registered until it
* is <i>deregistered</i>. This involves deallocating whatever resources were
* allocated to the channel by the selector.
*
只要通道注册到选择器中,直到调用deregistered方法,才能将通道从选择器移除。
无论选择器分配什么资源给通道,deregistered方法被调用时,相关资源将会被收回。
* <p> A channel cannot be deregistered directly; instead, the key representing
* its registration must be <i>cancelled</i>. Cancelling a key requests that
* the channel be deregistered during the selector's next selection operation.
* A key may be cancelled explicitly by invoking its {@link
* SelectionKey#cancel() cancel} method. All of a channel's keys are cancelled
* implicitly when the channel is closed, whether by invoking its {@link
* Channel#close close} method or by interrupting a thread blocked in an I/O
* operation upon the channel.
*
通道不能直接从选择器反注册;取而代之的是,通过注册时返回的SelectionKey,SelectionKey
是必须可以被cancelled的。SelectionKey取消后,在选择器下一次选择操作中,通道将会被反注册。
可以通道SelectionKey#cancel的方法显示地取消SelectionKey。在通道关闭时,无论是否调用
Channel#close,阻塞IO操作线程是否被中断,所有跟通道相关联的SelectionKey将会被取消。
* <p> If the selector itself is closed then the channel will be deregistered,
* and the key representing its registration will be invalidated, without
* further delay.
*
如果选择器自己关闭,所有注册到选择器的通道将会被反注册,同时与通道相关的SelectionKey,
将会立即无效。
* <p> A channel may be registered at most once with any particular selector.
*
一个通道可以被多次注册到一个特殊的选择器中。
* <p> Whether or not a channel is registered with one or more selectors may be
* determined by invoking the {@link #isRegistered isRegistered} method.
*
判断一个线程是否一次或多次注册到选择器,我们可以通过isRegistered方法来确定。
* <p> Selectable channels are safe for use by multiple concurrent
* threads.

*
可选择的通道在多线程并发访问的情况下,必须是线程安全的。
*
* <a name="bm">
* <h4>Blocking mode</h4>
*
阻塞模式
* A selectable channel is either in <i>blocking</i> mode or in
* <i>non-blocking</i> mode. In blocking mode, every I/O operation invoked
* upon the channel will block until it completes. In non-blocking mode an I/O
* operation will never block and may transfer fewer bytes than were requested
* or possibly no bytes at all. The blocking mode of a selectable channel may
* be determined by invoking its {@link #isBlocking isBlocking} method.
*
一个可选择的通道要么是可阻塞的,要么是不可阻塞的。在阻塞模式下,通道的IO操作将会阻塞,直到
器完成。在非阻塞模式下,IO操作绝对不会被阻塞,IO操作可能接受少于请求的数据或者就没有。
通道的阻塞模式,我们可以通过#isBlocking方法来判断。
* Newly-created selectable channels are always in blocking mode.
* Non-blocking mode is most useful in conjunction with selector-based
* multiplexing. A channel must be placed into non-blocking mode before being
* registered with a selector, and may not be returned to blocking mode until
* it has been deregistered.
*
一个新创建的可选择通道总是阻塞模式。非阻塞模式在基于多路复用的选择器中非常有用,
一个通道在注册到选择器前,必须是非阻塞模式,直到反注册之前,都处于非阻塞模式中。
*
* @author Mark Reinhold
* @author JSR-51 Expert Group
* @since 1.4
*
* @see SelectionKey
* @see Selector
*/

public abstract class SelectableChannel
extends AbstractInterruptibleChannel
implements Channel
{

/**
* Initializes a new instance of this class.
*/
protected SelectableChannel() { }

/**
* Returns the provider that created this channel.
*
返回创建通道的提供者,这个在以后我们遇到时,才具体地将
* @return The provider that created this channel
*/
public abstract SelectorProvider provider();

/**
* Returns an [url=SelectionKey.html#opsets]operation set[/url]
* identifying this channel's supported operations. The bits that are set
* in this integer value denote exactly the operations that are valid for
* this channel. This method always returns the same value for a given
* concrete channel class.

*
返回通道支持的SelectionKey操作opsets。integer值中的bit位表示相关的操作,对于
本通道有效。本方法总是返回相同的值,在具体的通道中。
* @return The valid-operation set
*/
public abstract int validOps();

// Internal state:
// keySet, may be empty but is never null, typ. a tiny array
// boolean isRegistered, protected by key set
// regLock, lock object to prevent duplicate registrations
// boolean isBlocking, protected by regLock

/**
* Tells whether or not this channel is currently registered with any
* selectors. A newly-created channel is not registered.
*
潘丹当前通道是否注册到选择器。新创建的通道是非注册的。
* Due to the inherent delay between key cancellation and channel
* deregistration, a channel may remain registered for some time after all
* of its keys have been cancelled. A channel may also remain registered
* for some time after it is closed.

*
由于在SelectKey取消操作和通道反注册之间,存在内部的时延,在所有通道的SelectKey取消时,
有时一个通道可能仍处于注册状态。在通道关闭后,有时可能仍处于注册状态。
* @return <tt>true</tt> if, and only if, this channel is registered
*/
public abstract boolean isRegistered();
//
// sync(keySet) { return isRegistered; }

/**
* Retrieves the key representing the channel's registration with the given
* selector.
*
获取通道上次注册到选择器的SelectionKey,没有注册,则返回null
* @return The key returned when this channel was last registered with the
* given selector, or <tt>null</tt> if this channel is not
* currently registered with that selector
*/
public abstract SelectionKey keyFor(Selector sel);
//同步keySet,返回刚注册到选择器的SelectionKey
// sync(keySet) { return findKey(sel); }

/**
* Registers this channel with the given selector, returning a selection
* key.
*
注册通道到指定的选择器,并返回一个SelectionKey。
* If this channel is currently registered with the given selector then
* the selection key representing that registration is returned. The key's
* interest set will have been changed to <tt>ops</tt>, as if by invoking
* the {@link SelectionKey#interestOps(int) interestOps(int)} method. If
* the <tt>att</tt> argument is not <tt>null</tt> then the key's attachment
* will have been set to that value. A {@link CancelledKeyException} will
* be thrown if the key has already been cancelled.
*
如果通道当前已经注册到指定的选择器,表示注册器的SelectionKey将会被返回。
只要SelectionKey#interestOps(int) 方法被调用,那么 SelectionKey关注事件将会被更新到ops中。
如果att参数不为null,则SelectionKey的attachment将会被赋值为att。如果SelectionKey已经被取消,
将抛出CancelledKeyException。
* Otherwise this channel has not yet been registered with the given
* selector, so it is registered and the resulting new key is returned.
* The key's initial interest set will be <tt>ops</tt> and its attachment
* will be <tt>att</tt>.
*
如果通道还没有注册到通道,在注册完成后,将会返回一个新创建的SelectionKey,
SelectionKey的初始关注集将会被设值为ops,attachment设值为att。
* <p> This method may be invoked at any time. If this method is invoked
* while another invocation of this method or of the {@link
* #configureBlocking(boolean) configureBlocking} method is in progress
* then it will first block until the other operation is complete. This
* method will then synchronize on the selector's key set and therefore may
* block if invoked concurrently with another registration or selection
* operation involving the same selector.

*
此方可以被任何时候调用。当其他方法调用或者configureBlocking(boolean)正在进行,
调用此方法将会阻塞,直到其他操作完成。此方法将会同步选择器的SelectionKey集合,
因此如果其他通道注册或选择操作涉及到同一个选择器等操作并发,此操作也许会阻塞。
* If this channel is closed while this operation is in progress then
* the key returned by this method will have been cancelled and will
* therefore be invalid.

*
当操作正在进行,但通道被关闭,那么注册返回的注册器SelectionKey将会被取消,
并无效。
* @param sel,选择器
* The selector with which this channel is to be registered
*
* @param ops,关注的操作事件
* The interest set for the resulting key
*
* @param att 附加对象
* The attachment for the resulting key; may be <tt>null</tt>
*
* @throws ClosedChannelException,如果通道关闭抛出ClosedChannelException
* If this channel is closed
*
* @throws ClosedSelectorException,如果选择器关闭抛出ClosedSelectorException
* If the selector is closed
*
* @throws IllegalBlockingModeException,如果通道为阻塞模式,则抛出IllegalBlockingModeException
* If this channel is in blocking mode
*
* @throws IllegalSelectorException,如果通道不是通过与选择器相同的provider创建,
则抛出IllegalSelectorException
* If this channel was not created by the same provider
* as the given selector
*
* @throws CancelledKeyException,如果通道已经注册到选择器,但是相关的SelectionKey已经被取消,
抛出CancelledKeyException
* If this channel is currently registered with the given selector
* but the corresponding key has already been cancelled
*
* @throws IllegalArgumentException
* If a bit in the <tt>ops</tt> set does not correspond to an
* operation that is supported by this channel, that is, if
* <tt>set & ~validOps() != 0</tt>
*如果关注的事件ops是通道不支持的事件,则抛出IllegalArgumentException,我们
可以通过set & ~validOps() != 0来判断,事件ops参数为否合法。
* @return A key representing the registration of this channel with
* the given selector
*/
public abstract SelectionKey register(Selector sel, int ops, Object att)
throws ClosedChannelException;
//下面是,简单的通道注册到选择器的过程
// sync(regLock) {
// sync(keySet) { look for selector }
// if (channel found) { set interest ops -- may block in selector;
// return key; }
// create new key -- may block somewhere in selector;
// sync(keySet) { add key; }
// attach(attachment);
// return key;
遍历选择的SelectionKey集合,查看通道是否存在,存在更新关注事件集,否则创建新的SelectionKey
并添加到SelectionKey集合中。
// }

/**
* Registers this channel with the given selector, returning a selection
* key.
*
* An invocation of this convenience method of the form
*
* <blockquote><tt>sc.register(sel, ops)</tt></blockquote>
*
* behaves in exactly the same way as the invocation
*
* <blockquote><tt>sc.{@link
* #register(java.nio.channels.Selector,int,java.lang.Object)
* register}(sel, ops, null)</tt></blockquote>
*
* @param sel
* The selector with which this channel is to be registered
*
* @param ops
* The interest set for the resulting key
*
* @throws ClosedChannelException
* If this channel is closed
*
* @throws ClosedSelectorException
* If the selector is closed
*
* @throws IllegalBlockingModeException
* If this channel is in blocking mode
*
* @throws IllegalSelectorException
* If this channel was not created by the same provider
* as the given selector
*
* @throws CancelledKeyException
* If this channel is currently registered with the given selector
* but the corresponding key has already been cancelled
*
* @throws IllegalArgumentException
* If a bit in <tt>ops</tt> does not correspond to an operation
* that is supported by this channel, that is, if <tt>set &
* ~validOps() != 0</tt>
*
* @return A key representing the registration of this channel with
* the given selector
*/
public final SelectionKey register(Selector sel, int ops)
throws ClosedChannelException
{
//委托给 register(Selector sel, int ops, Object att)
return register(sel, ops, null);
}

/**
* Adjusts this channel's blocking mode.
*调整通道的阻塞模式
* <p> If this channel is registered with one or more selectors then an
* attempt to place it into blocking mode will cause an {@link
* IllegalBlockingModeException} to be thrown.
*如果通道已经注册到选择器,尝试将通道设置为阻塞模式将抛出IllegalBlockingModeException,
即注册到选择器的通道必须是非阻塞的。
* <p> This method may be invoked at any time. The new blocking mode will
* only affect I/O operations that are initiated after this method returns.
* For some implementations this may require blocking until all pending I/O
* operations are complete.
*
这个方法可以在任何时候调用。在方法返回时,新的阻塞模式将会影响到已经开始的操作。
在一些实现版本中,可能需要阻塞到所有的已经开始的IO操作完成。
* <p> If this method is invoked while another invocation of this method or
* of the {@link #register(Selector, int) register} method is in progress
* then it will first block until the other operation is complete.

*
当前其他方法调用或者通道注册到选择器操作正在进行时,此方法调用将会阻塞,直到
其他操作完成。
* @param block If <tt>true</tt> then this channel will be placed in
* blocking mode; if <tt>false</tt> then it will be placed
* non-blocking mode
*true为阻塞模式,false为非阻塞模式
* @return This selectable channel
*返回一个可选择的通道
* @throws ClosedChannelException
* If this channel is closed
*如果通道已经关闭,则抛出ClosedChannelException
* @throws IllegalBlockingModeException
* If <tt>block</tt> is <tt>true</tt> and this channel is
* registered with one or more selectors
*当通道已经注册到选择器,设置通道为阻塞模式将会抛出IllegalBlockingModeException
* @throws IOException
* If an I/O error occurs
*/
public abstract SelectableChannel configureBlocking(boolean block)
throws IOException;
//设置阻塞模式的简单示例
// sync(regLock) {
// sync(keySet) { throw IBME if block && isRegistered; }
// change mode;
// }

/**
* Tells whether or not every I/O operation on this channel will block
* until it completes. A newly-created channel is always in blocking mode.
*判断通道上的每一个IO操作是否为阻塞模式,直到操作完成。一个新创建的通道为阻塞模式。
* If this channel is closed then the value returned by this method is
* not specified.

*如果通道已经关闭,返回值是不确定
* @return <tt>true</tt> if, and only if, this channel is in blocking mode
*/
public abstract boolean isBlocking();

/**
* Retrieves the object upon which the {@link #configureBlocking
* configureBlocking} and {@link #register register} methods synchronize.
* This is often useful in the implementation of adaptors that require a
* specific blocking mode to be maintained for a short period of time.
*
*返回#configureBlocking和#register方法的同步对象。
* @return The blocking-mode lock object
*/
public abstract Object blockingLock();

}

[size=medium][b]总结:[/b][/size]
[color=blue]SelectableChannel是一个可选择的通道,可以注册到选择器,通道在创建时为阻塞模式,必选先通过configureBlocking方法,设置通道为非阻塞模式,才可以注册到注册器。我们可以通过validOps方法验证通道注册到选择器的事件,是否为通道支持的事件,可以通过isRegistered方法判断是否注册到选择器,用isBlocking方法判断通道是否为阻塞模式,用register方法将通道感兴趣的事件注册到选择器中,并返回一个注册器SelectionKey。[/color]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值