- 浏览: 950721 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Channel接口定义:http://donald-draper.iteye.com/blog/2369111
AbstractInterruptibleChannel接口定义:http://donald-draper.iteye.com/blog/2369238
SelectableChannel接口定义:http://donald-draper.iteye.com/blog/2369317
在我们上一篇SelectableChannel接口定义文章中,提到很多SelectionKey概念,
当通道注册到注册器时,返回一个SelectionKey,今天我们来看一个SelectionKey:
总结:
SelectionKey表示一个可选择通道与选择器关联的注册器,可以简单理解为一个token。SelectionKey包含两个操作集,分别是兴趣操作事件集interestOps和通道就绪操作事件集readyOps,每个操作集用一个Integer来表示。interestOps用于选择器判断在下一个选择操作的过程中,操作事件是否是通道关注的。兴趣操作事件集在SelectionKey创建时,初始化为注册选择器时的opt值,这个值可能通过interestOps(int)会改变。SelectionKey的readyOps表示一个通道已经准备就绪的操作事件,但不能保证在没有引起线程阻塞的情况下,就绪的操作事件会被线程执行。在一个选择操作完成后,大部分情况下就绪操作事件集会立即更新。如果外部的事件或在通道有IO操作,就绪操作事件集可能不准确。如果需要经常关联一些应用的特殊数据到SelectionKey,比如一个object表示一个高层协议的状态,object用于通知实现协议处理器。所以,SelectionKey支持通过attach方法将一个对象附加的SelectionKey的attachment上。attachment可以通过#attachment方法进行修改。SelectionKey定义了所有的操作事件,但是具体通道支持的操作事件依赖于具体的通道。所有可选择的通道都可以通过validOps方法,判断一个操作事件是否被通道所支持。测试一个不被通道所支持的通道,将会抛出相关的运行时异常。SelectionKey多线程并发访问时,是线程安全的。读写兴趣操作事件集的操作都将同步到,选择器的具体操作。同步器执行过程是依赖实现的:在一个本地实现版本中,如果一个选择操作正在进行,读写兴趣操作事件集也许会不确定地阻塞;在一个高性能的实现版本中,可能会简单阻塞。无论任何时候,一个选择操作在操作开始时,选择器总是占用着兴趣操作事件集的值。SelectionKey可以简单理解为通道和选择器的映射关系,并定义了相关的操作事件,分别为OP_READ,OP_WRITE,OP_CONNECT,OP_ACCEPT值分别是,int的值的第四为分别为1,级1,4,8,16。用一个AtomicReferenceFieldUpdater原子更新attachment。
附:
在来看选择key的具体实现
从SelectionKeyImpl的定义可以看出,SelectionKeyImpl关联一个可选择通道和选择器,
并实现了兴趣事件集和就绪事件集的设置和查询操作,其中readyOps和interestOps多了nio为前缀的方法,与无前缀的方法,基本无异,只是在nioInterestOps设置兴趣事件集是委托给了
具体的可选择通道的translateAndSetInterestOps方法。
再看一下SelChImpl选择通道的定义:
选择key中的通道问什么是SelChImpl,我们看一下ServerSocketChannel的具体实现ServerSocketChannelImpl的定义,我们就会明白为什么是SelChImpl,
关于ServerSocketChannel为什么是ServerSocketChannelImpl,这个我们会在下一篇文章
SelectorProvider定义中,会说。
在SelChImpl接口定义中,我们看到 getFD返回的是FileDescriptor
再来看一下FileDescriptor是什么意思?好吧文章太长了,我们另开一篇再看。
FileDescriptor定义:http://donald-draper.iteye.com/blog/2369957
AbstractInterruptibleChannel接口定义:http://donald-draper.iteye.com/blog/2369238
SelectableChannel接口定义:http://donald-draper.iteye.com/blog/2369317
在我们上一篇SelectableChannel接口定义文章中,提到很多SelectionKey概念,
当通道注册到注册器时,返回一个SelectionKey,今天我们来看一个SelectionKey:
package java.nio.channels; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.io.IOException; /** * A token representing the registration of a {@link SelectableChannel} with a * {@link Selector}. * SelectionKey表示一个可选择通道与选择器关联的注册器,可以简单理解为一个token。 * A selection key is created each time a channel is registered with a * selector. A key remains valid until it is <i>cancelled</i> by invoking its * {@link #cancel cancel} method, by closing its channel, or by closing its * selector. Cancelling a key does not immediately remove it from its * selector; it is instead added to the selector's <a * href="Selector.html#ks"><i>cancelled-key set</i></a> for removal during the * next selection operation. The validity of a key may be tested by invoking * its {@link #isValid isValid} method. * SelectionKey在每次通道注册到选择器时创建。SelectionKey在其调用取消方法,或自己的通道 关闭,或关联的选择器关闭之前,都是有效。取消一个SelectionKey,不会立刻从选择器移除; 而是在下一次通选器选择操作的过程,取消的SelectionKey从SelectionKey集合移除是无效的。 我们可以通过#isValid判断一个SelectionKey是否有效。 * <a name="opsets"> * * represented as * integer values. Each bit of an operation set denotes a category of * selectable operations that are supported by the key's channel. * SelectionKey包含两个操作集,每个操作集用一个Integer来表示,int值中的低四位的bit 用于表示通道支持的可选操作种类。 * [list] * * <li><p> The <i>interest set</i> determines which operation categories will * be tested for readiness the next time one of the selector's selection * methods is invoked. The interest set is initialized with the value given * when the key is created; it may later be changed via the {@link * #interestOps(int)} method. </li> *interest集合决定了选择器在下一个选择操作的过程中,操作事件是否是通道关注的。兴趣操作事件集 在SelectionKey创建时,初始化为注册选择器时的opt值,这个值可能通过interestOps(int)会改变。 * <li> The <i>ready set</i> identifies the operation categories for which * the key's channel has been detected to be ready by the key's selector. * The ready set is initialized to zero when the key is created; it may later * be updated by the selector during a selection operation, but it cannot be * updated directly. </li> *ready集合表示通过选择器探测到通道已经准备就绪的操作事件。在SelectionKey创建时时, 就绪操作事件集值为0,在选择器的选择操作中可能会更新,但是不能直接的更新。 * [/list] * * That a selection key's ready set indicates that its channel is ready for * some operation category is a hint, but not a guarantee, that an operation in * such a category may be performed by a thread without causing the thread to * block. A ready set is most likely to be accurate immediately after the * completion of a selection operation. It is likely to be made inaccurate by * external events and by I/O operations that are invoked upon the * corresponding channel. * SelectionKey的ready集合表示一个通道已经准备就绪的操作事件,但不能保证在没有引起线程 阻塞的情况下,就绪的操作事件会被线程执行。在一个选择操作完成后,就绪操作事件集, 大部分情况下回立即,更新。如果外部的事件或在通道有IO操作,就绪操作事件集可能不准确。 * <p> This class defines all known operation-set bits, but precisely which * bits are supported by a given channel depends upon the type of the channel. * Each subclass of {@link SelectableChannel} defines an {@link * SelectableChannel#validOps() validOps()} method which returns a set * identifying just those operations that are supported by the channel. An * attempt to set or test an operation-set bit that is not supported by a key's * channel will result in an appropriate run-time exception. * SelectionKey定义了所有的操作事件,但是具体通道支持的操作事件依赖于具体的通道。 所有可选择的通道都可以通过validOps方法,判断一个操作事件是否被通道所支持。测试一个 不被通道所支持的通道,将会抛出相关的运行时异常。 * <p> It is often necessary to associate some application-specific data with a * selection key, for example an object that represents the state of a * higher-level protocol and handles readiness notifications in order to * implement that protocol. Selection keys therefore support the * <i>attachment</i> of a single arbitrary object to a key. An object can be * attached via the {@link #attach attach} method and then later retrieved via * the {@link #attachment() attachment} method. * 如果需要经常关联一些应用的特殊数据到SelectionKey,比如一个object表示一个高层协议的 状态,object用于通知实现协议处理器。所以,SelectionKey支持通过attach方法将一个对象 附加的SelectionKey的attachment上。attachment可以通过#attachment方法进行修改。 * <p> Selection keys are safe for use by multiple concurrent threads. The * operations of reading and writing the interest set will, in general, be * synchronized with certain operations of the selector. Exactly how this * synchronization is performed is implementation-dependent: In a naive * implementation, reading or writing the interest set may block indefinitely * if a selection operation is already in progress; in a high-performance * implementation, reading or writing the interest set may block briefly, if at * all. In any case, a selection operation will always use the interest-set * value that was current at the moment that the operation began. * SelectionKey多线程并发访问时,是线程安全的。读写兴趣操作事件集的操作都将同步到, 选择器的具体操作。同步器执行过程是依赖实现的:在一个本地实现版本中,如果一个选择操作正在 进行,读写兴趣操作事件集也许会不确定地阻塞;在一个高性能的实现版本中,可能会简单阻塞。 无论任何时候,一个选择操作在操作开始时,选择器总是占用着兴趣操作事件集的值。 * * @author Mark Reinhold * @author JSR-51 Expert Group * @since 1.4 * * @see SelectableChannel * @see Selector */ public abstract class SelectionKey { /** * Constructs an instance of this class. */ protected SelectionKey() { } // -- Channel and selector operations -- /** * Returns the channel for which this key was created. This method will * continue to return the channel even after the key is cancelled. * 返回SelectionKey关联的通道,即使在SelectionKey取消后,这个方法继续返回通道 * @return This key's channel */ public abstract SelectableChannel channel(); /** * Returns the selector for which this key was created. This method will * continue to return the selector even after the key is cancelled. </p> * 返回SelectionKey关联的选择器,即使在SelectionKey取消后,这个方法继续返回选择器 * @return This key's selector */ public abstract Selector selector(); /** * Tells whether or not this key is valid. *判断一个SelectionKey是否有效 * A key is valid upon creation and remains so until it is cancelled, * its channel is closed, or its selector is closed. * 在SelectionKey被取消,通道关闭或选择器关闭之前,SelectionKey都是有效的 * @return <tt>true</tt> if, and only if, this key is valid */ public abstract boolean isValid(); /** * Requests that the registration of this key's channel with its selector * be cancelled. Upon return the key will be invalid and will have been * added to its selector's cancelled-key set. The key will be removed from * all of the selector's key sets during the next selection operation. * 取消SelectionKey关联的通道与选择器的注册器。取消后,key将无效,同时被添加到选择器的 取消SelectionKey集合,在选择器下一次选择操作中,将会被移除。 * If this key has already been cancelled then invoking this method has * no effect. Once cancelled, a key remains forever invalid. * 如果SelectionKey已经被取消,再次调用无效,一次取消,永久无效。 * This method may be invoked at any time. It synchronizes on the * selector's cancelled-key set, and therefore may block briefly if invoked * concurrently with a cancellation or selection operation involving the * same selector. 方法可以在任何时候调用。将同步到选择器的cancelled-key集合中,如果调用时, 相关选择器正在取消或选择操作,则取消SelectionKey操作也许会简单的阻塞。 */ public abstract void cancel(); // -- Operation-set accessors -- /** * Retrieves this key's interest set. * 获取SelectionKey的兴趣操作事件集interestOps * It is guaranteed that the returned set will only contain operation * bits that are valid for this key's channel. * 操作保证返回的兴趣事件集中的事件是通道所支持的 * This method may be invoked at any time. Whether or not it blocks, * and for how long, is implementation-dependent. * 方法可以在任何时候调用,是否阻塞及阻塞多久,需要根据具体的实现。 * @return This key's interest set * * @throws CancelledKeyException * If this key has been cancelled 如果SelectionKey已经被取消,则抛出CancelledKeyException */ public abstract int interestOps(); /** * Sets this key's interest set to the given value. * 设置兴趣操作事件集为指定的值 * This method may be invoked at any time. Whether or not it blocks, * and for how long, is implementation-dependent. *方法可以在任何时候调用,是否阻塞及阻塞多久,需要根据具体的实现。 * @param ops The new interest set * * @return This selection key * * @throws IllegalArgumentException * If a bit in the set does not correspond to an operation that * is supported by this key's channel, that is, if * <tt>(ops & ~channel().validOps()) != 0</tt> *如果所设置的操作事件集,有不被通道支持的事件,将抛出IllegalArgumentException * @throws CancelledKeyException * If this key has been cancelled */如果SelectionKey已经被取消,则抛出CancelledKeyException public abstract SelectionKey interestOps(int ops); /** * Retrieves this key's ready-operation set. *获取已经准备就绪的操作事件集 * It is guaranteed that the returned set will only contain operation * bits that are valid for this key's channel. *保证返回的就绪操作事件中的事件是通道所支持的 * @return This key's ready-operation set * * @throws CancelledKeyException * If this key has been cancelled */ public abstract int readyOps(); // -- Operation bits and bit-testing convenience methods -- /** * Operation-set bit for read operations. *读操作事件 * Suppose that a selection key's interest set contains * <tt>OP_READ</tt> at the start of a <a * href="Selector.html#selop">selection operation</a>. If the selector * detects that the corresponding channel is ready for reading, has reached * end-of-stream, has been remotely shut down for further reading, or has * an error pending, then it will add <tt>OP_READ</tt> to the key's * ready-operation set and add the key to its selected-key set. 假设在选择器选择操作开始时,SelectionKey的兴趣操作事件集包含OP_READ事件。 如果选择器探测到相关的通道已经准备好读数据,已经到达流的末端,或流即将关闭, 或pend数据出错,选择器将会添加读操作事件到SelectionKey的就绪操作事件集,并 添加到可以选择的SelectionKey集。 */ public static final int OP_READ = 1 << 0; /** * Operation-set bit for write operations. *写操作事件 * Suppose that a selection key's interest set contains * <tt>OP_WRITE</tt> at the start of a <a * href="Selector.html#selop">selection operation</a>. If the selector * detects that the corresponding channel is ready for writing, has been * remotely shut down for further writing, or has an error pending, then it * will add <tt>OP_WRITE</tt> to the key's ready set and add the key to its * selected-key set. 假设在选择器选择操作开始时,SelectionKey的兴趣操作事件集包含OP_WRITE事件。 如果选择器探测到相关的通道已经准备好写数据,或流即将关闭, 或pend数据出错,选择器将会添加写操作事件到SelectionKey的就绪操作事件集,并 添加到可以选择的SelectionKey集。 */ public static final int OP_WRITE = 1 << 2; /** * Operation-set bit for socket-connect operations. </p> *socket连接操作事件 * Suppose that a selection key's interest set contains * <tt>OP_CONNECT</tt> at the start of a <a * href="Selector.html#selop">selection operation</a>. If the selector * detects that the corresponding socket channel is ready to complete its * connection sequence, or has an error pending, then it will add * <tt>OP_CONNECT</tt> to the key's ready set and add the key to its * selected-key set. 假设在选择器选择操作开始时,SelectionKey的兴趣操作事件集包含OP_CONNECT事件。 如果选择器探测到相关的socket通道已经完成连接,或pend数据出错,选择器将会添加连接操作事件 到SelectionKey的就绪操作事件集,并添加到可以选择的SelectionKey集。 */ public static final int OP_CONNECT = 1 << 3; /** * Operation-set bit for socket-accept operations. </p> *socket接受操作事件 * Suppose that a selection key's interest set contains * <tt>OP_ACCEPT</tt> at the start of a <a * href="Selector.html#selop">selection operation</a>. If the selector * detects that the corresponding server-socket channel is ready to accept * another connection, or has an error pending, then it will add * <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its * selected-key set. 假设在选择器选择操作开始时,SelectionKey的兴趣操作事件集包含OP_ACCEPT事件。 如果选择器探测到相关的server-socket通道已经准备好接受另一个连接, 或pend数据出错,选择器将会添加OP_ACCEPT事件到SelectionKey的就绪操作事件集, 并添加到可以选择的SelectionKey集。 */ public static final int OP_ACCEPT = 1 << 4; /** * Tests whether this key's channel is ready for reading. *测试SelectionKey的通道是否准备好读操作事件 * An invocation of this method of the form <tt>k.isReadable()</tt> * behaves in exactly the same way as the expression * * <blockquote> * k.readyOps() & OP_READ != 0</pre></blockquote> * * <p> If this key's channel does not support read operations then this * method always returns <tt>false</tt>. * * @return <tt>true</tt> if, and only if, * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_READ</tt> is * nonzero * * @throws CancelledKeyException * If this key has been cancelled */ public final boolean isReadable() { return (readyOps() & OP_READ) != 0; } /** * Tests whether this key's channel is ready for writing. *测试SelectionKey的通道是否准备好写操作事件 * An invocation of this method of the form <tt>k.isWritable()</tt> * behaves in exactly the same way as the expression * * <blockquote><pre> * k.readyOps() & OP_WRITE != 0</pre></blockquote> * * <p> If this key's channel does not support write operations then this * method always returns <tt>false</tt>. * * @return <tt>true</tt> if, and only if, * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_WRITE</tt> * is nonzero * * @throws CancelledKeyException * If this key has been cancelled */ public final boolean isWritable() { return (readyOps() & OP_WRITE) != 0; } /** * Tests whether this key's channel has either finished, or failed to * finish, its socket-connection operation. *测试SelectionKey的socket通道连接操作是否完成 * An invocation of this method of the form <tt>k.isConnectable()</tt> * behaves in exactly the same way as the expression * * <blockquote><pre> * k.readyOps() & OP_CONNECT != 0</pre></blockquote> * * <p> If this key's channel does not support socket-connect operations * then this method always returns <tt>false</tt>. * * @return <tt>true</tt> if, and only if, * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_CONNECT</tt> * is nonzero * * @throws CancelledKeyException * If this key has been cancelled */ public final boolean isConnectable() { return (readyOps() & OP_CONNECT) != 0; } /** * Tests whether this key's channel is ready to accept a new socket * connection. *测试SelectionKey的serversocket通道是否准备好接受一个新的socket的连接 * An invocation of this method of the form <tt>k.isAcceptable()</tt> * behaves in exactly the same way as the expression * * <blockquote><pre> * k.readyOps() & OP_ACCEPT != 0</pre></blockquote> * * <p> If this key's channel does not support socket-accept operations then * this method always returns <tt>false</tt>. * * @return <tt>true</tt> if, and only if, * <tt>readyOps()</tt> <tt>&</tt> <tt>OP_ACCEPT</tt> * is nonzero * * @throws CancelledKeyException * If this key has been cancelled */ public final boolean isAcceptable() { return (readyOps() & OP_ACCEPT) != 0; } // -- Attachments -- private volatile Object attachment = null;//附加对象 //原子更新SelectionKey的附加对象,负载Updater private static final AtomicReferenceFieldUpdater<SelectionKey,Object> attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater( SelectionKey.class, Object.class, "attachment" ); /** * Attaches the given object to this key. *将指定的对象设为附加对象 * An attached object may later be retrieved via the {@link #attachment() * attachment} method. Only one object may be attached at a time; invoking * this method causes any previous attachment to be discarded. The current * attachment may be discarded by attaching <tt>null</tt>. * * @param ob * The object to be attached; may be <tt>null</tt> * * @return The previously-attached object, if any, * otherwise <tt>null</tt> */ public final Object attach(Object ob) { return attachmentUpdater.getAndSet(this, ob); } /** * Retrieves the current attachment. *返回当前附加对象 * @return The object currently attached to this key, * or <tt>null</tt> if there is no attachment */ public final Object attachment() { return attachment; } }
总结:
SelectionKey表示一个可选择通道与选择器关联的注册器,可以简单理解为一个token。SelectionKey包含两个操作集,分别是兴趣操作事件集interestOps和通道就绪操作事件集readyOps,每个操作集用一个Integer来表示。interestOps用于选择器判断在下一个选择操作的过程中,操作事件是否是通道关注的。兴趣操作事件集在SelectionKey创建时,初始化为注册选择器时的opt值,这个值可能通过interestOps(int)会改变。SelectionKey的readyOps表示一个通道已经准备就绪的操作事件,但不能保证在没有引起线程阻塞的情况下,就绪的操作事件会被线程执行。在一个选择操作完成后,大部分情况下就绪操作事件集会立即更新。如果外部的事件或在通道有IO操作,就绪操作事件集可能不准确。如果需要经常关联一些应用的特殊数据到SelectionKey,比如一个object表示一个高层协议的状态,object用于通知实现协议处理器。所以,SelectionKey支持通过attach方法将一个对象附加的SelectionKey的attachment上。attachment可以通过#attachment方法进行修改。SelectionKey定义了所有的操作事件,但是具体通道支持的操作事件依赖于具体的通道。所有可选择的通道都可以通过validOps方法,判断一个操作事件是否被通道所支持。测试一个不被通道所支持的通道,将会抛出相关的运行时异常。SelectionKey多线程并发访问时,是线程安全的。读写兴趣操作事件集的操作都将同步到,选择器的具体操作。同步器执行过程是依赖实现的:在一个本地实现版本中,如果一个选择操作正在进行,读写兴趣操作事件集也许会不确定地阻塞;在一个高性能的实现版本中,可能会简单阻塞。无论任何时候,一个选择操作在操作开始时,选择器总是占用着兴趣操作事件集的值。SelectionKey可以简单理解为通道和选择器的映射关系,并定义了相关的操作事件,分别为OP_READ,OP_WRITE,OP_CONNECT,OP_ACCEPT值分别是,int的值的第四为分别为1,级1,4,8,16。用一个AtomicReferenceFieldUpdater原子更新attachment。
附:
package java.nio.channels.spi; import java.nio.channels.*; /** * Base implementation class for selection keys. * * <p> This class tracks the validity of the key and implements cancellation. * * @author Mark Reinhold * @author JSR-51 Expert Group * @since 1.4 */ public abstract class AbstractSelectionKey extends SelectionKey { /** * Initializes a new instance of this class. </p> */ protected AbstractSelectionKey() { } //可见的选择key有效性 private volatile boolean valid = true; //判断是否有效 public final boolean isValid() { return valid; } //置选择key为无效 void invalidate() { // package-private valid = false; } /** * Cancels this key. * * <p> If this key has not yet been cancelled then it is added to its * selector's cancelled-key set while synchronized on that set. </p> 取消选择key,如果选择key还没有完全取消,则同步到选择器的取消选择key集合中 */ public final void cancel() { // Synchronizing "this" to prevent this key from getting canceled // multiple times by different threads, which might cause race // condition between selector's select() and channel's close(). //同步this,为了阻止不同线程多次调用取消操作竞争,比如选择的选择操作和通道 //的关闭操作 synchronized (this) { if (valid) { valid = false; //委托给选择器 ((AbstractSelector)selector()).cancel(this); } } } }
在来看选择key的具体实现
class SelectionKeyImpl extends AbstractSelectionKey { final SelChImpl channel;//key关联的通道 final SelectorImpl selector;//key关联的选择器 private int index;//key索引(猜测不是通道的key集合索引,就是选择器的可集合索引) private volatile int interestOps;//兴趣操作事件集 private int readyOps;//就绪操作事件集 //构造 SelectionKeyImpl(SelChImpl selchimpl, SelectorImpl selectorimpl) { channel = selchimpl; selector = selectorimpl; } //返回key关联通道 public SelectableChannel channel() { return (SelectableChannel)channel; } //返回key关联的选择器 public Selector selector() { return selector; } //设置索引 int getIndex() { return index; } //设置索引 void setIndex(int i) { index = i; } //判断key是否有效 private void ensureValid() { if(!isValid()) throw new CancelledKeyException(); else return; } //返回兴趣操作事件集 public int interestOps() { ensureValid(); return interestOps; } //设置兴趣操作事件集 public SelectionKey interestOps(int i) { ensureValid(); //实际设置兴趣操作事件集 return nioInterestOps(i); } //实际设置兴趣操作事件集 SelectionKey nioInterestOps(int i) { if((i & ~channel().validOps()) != 0) { //事件无效,抛出IllegalArgumentException throw new IllegalArgumentException(); } else { //否则委托给通道,这个我们留在后面看 channel.translateAndSetInterestOps(i, this); interestOps = i; return this; } } //返回兴趣操作事件集 int nioInterestOps() { return interestOps; } //返回就绪事件集 public int readyOps() { ensureValid(); return readyOps; } //设置就绪事件集 void nioReadyOps(int i) { readyOps = i; } //返回就绪事件集 int nioReadyOps() { return readyOps; } }
从SelectionKeyImpl的定义可以看出,SelectionKeyImpl关联一个可选择通道和选择器,
并实现了兴趣事件集和就绪事件集的设置和查询操作,其中readyOps和interestOps多了nio为前缀的方法,与无前缀的方法,基本无异,只是在nioInterestOps设置兴趣事件集是委托给了
具体的可选择通道的translateAndSetInterestOps方法。
再看一下SelChImpl选择通道的定义:
interface SelChImpl extends Channel { //获取文件描述 public abstract FileDescriptor getFD(); public abstract int getFDVal(); //更新就绪事件集 public abstract boolean translateAndUpdateReadyOps(int i, SelectionKeyImpl selectionkeyimpl); //设置就绪事件集 public abstract boolean translateAndSetReadyOps(int i, SelectionKeyImpl selectionkeyimpl); //设置兴趣事件集 public abstract void translateAndSetInterestOps(int i, SelectionKeyImpl selectionkeyimpl); public abstract int validOps(); public abstract void kill() throws IOException; }
选择key中的通道问什么是SelChImpl,我们看一下ServerSocketChannel的具体实现ServerSocketChannelImpl的定义,我们就会明白为什么是SelChImpl,
class ServerSocketChannelImpl extends ServerSocketChannel implements SelChImpl
关于ServerSocketChannel为什么是ServerSocketChannelImpl,这个我们会在下一篇文章
SelectorProvider定义中,会说。
在SelChImpl接口定义中,我们看到 getFD返回的是FileDescriptor
再来看一下FileDescriptor是什么意思?好吧文章太长了,我们另开一篇再看。
FileDescriptor定义:http://donald-draper.iteye.com/blog/2369957
发表评论
-
文件通道解析二(文件锁,关闭通道)
2017-05-16 23:17 992文件通道解析一(读写操作,通道数据传输等):http://do ... -
文件通道解析一(读写操作,通道数据传输等)
2017-05-16 10:04 1101Reference定义(PhantomRefere ... -
文件通道创建方式综述
2017-05-15 17:39 931Reference定义(PhantomReference,Cl ... -
文件读写方式简单综述后续(文件,流构造)
2017-05-14 23:04 1398Java Socket通信实例:http://donald-d ... -
文件读写方式简单综述
2017-05-14 11:13 1068Java Socket通信实例:http://donald-d ... -
FileChanne定义
2017-05-12 23:28 869文件读写方式简单综述:http://donald-draper ... -
SeekableByteChannel接口定义
2017-05-11 08:43 1120ByteChannel,分散聚集通道接口的定义(SocketC ... -
FileChannel示例
2017-05-11 08:37 905前面我们看过socket通道,datagram通道,以管道Pi ... -
PipeImpl解析
2017-05-11 08:41 837ServerSocketChannel定义:http://do ... -
Pipe定义
2017-05-10 09:07 839Channel接口定义:http://donald-drape ... -
NIO-Pipe示例
2017-05-10 08:47 846PipeImpl解析:http://donald-draper ... -
DatagramChannelImpl 解析四(地址绑定,关闭通道等)
2017-05-10 08:27 690DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析三(多播)
2017-05-10 08:20 1686DatagramChannelImpl 解析一(初始化):ht ... -
NIO-UDP实例
2017-05-09 12:32 1514DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析二(报文发送与接收)
2017-05-09 09:03 1341DatagramChannelImpl 解析一(初始化):ht ... -
DatagramChannelImpl 解析一(初始化)
2017-05-08 21:52 1328Channel接口定义:http://donald-drape ... -
MembershipKeyImpl 简介
2017-05-08 09:11 870MembershipKey定义:http://donald-d ... -
DatagramChannel定义
2017-05-07 23:13 1182Channel接口定义:http://donald-drape ... -
MulticastChanne接口定义
2017-05-07 13:45 1067NetworkChannel接口定义:ht ... -
MembershipKey定义
2017-05-06 16:20 829package java.nio.channels; i ...
相关推荐
同时只要在就绪的SelectionKey列表中有至少一个SelectionKey存在,前述方法均将返回。 SocketChannel被Selector检查,检查其声称可以接受的状态是否已经产生,如当SocketChannel在向Selector注册是设置了可接受...
用Java实现非阻塞通信 java.nio包提供了支持非阻塞通信的类,主要包括: ● ServerSocketChannel:ServerSocket的替代类,支持阻塞通信与非...selected-keys集合中,就表示与这个SelectionKey对象相关的事件发生了。
2.客户端发送数据包请求到服务端,服务端将请求的SelectionKey压入“读消息生产者队列”,立即进入下一批Select 3.读消息消费者线程池中派遣一个就绪线程从客户端读取数据包DataPacket,并触发onReaded事件 4.开发...
如果你至今还是在怀疑Java的性能,说明你的思想和观念已经完全落伍了,Java一两年就应该用新的名词来定义。从JDK1.5开始又要提供关于线程、并发等新性能的支持,Java应用在游戏等适时领域方面的机会已经成熟,Java在...
NIO网络编程 Selector选择器 进行监听,是新连接或已经连接,读写数据 ...返回当前内部集合保存的所有selectionKey selectionKey 表示Selector与网络通道直接的关系 int OP_ACCEPT; 16 需要连接 int OP_C
NIO其核心概念包括Channel,Selector,SelectionKey,Buffer.
AbstractSelectionKey is the base implementation class for selection keys. It implements validation and cancellation methods.
NioSocket中服务端的处理过程可以分为5部: 1) 创建ServerSocketChannel,...4) Selector接收到请求后使用selectedKeys返回SelectionKey集合 5) 使用SelectionKey 获取Channel、Selector 和操作类型并进行操作。
SelectionKey key = r_channel.register(selector, SelectionKey.OP_READ); buf.clear(); File file = null; FileOutputStream fout = null;//文件输出流对象 RandomAccessFile raf = null;//创建临时文件对象 ...
- 选择键(SelectionKey) - 示例:简易的客户端服务器通信 - 总结 Java IO 是一个庞大的知识体系,很多人学着学着就会学懵了,包括我在内也是如此,所以本文将会从 Java 的 BIO 开始,一步一步深入学习,引出 ...
SelectionKey key = (SelectionKey) ite.next(); // 连接事件发生 if (key.isConnectable()) { SocketChannel channel = (SocketChannel) key .channel(); System.out.println("channel client ?" + ...
Selector类似一个调度中心,所有Channel都需要注册到选择器中,并绑定一个SelectionKey,绑定时还会指定要监听的事件,如:连接就绪、读就绪、写就绪等。可以调用Selector提供的API实现对发生监听事件的连接进行处理...
1. NIO完成网络编程 1.1 Selector选择器老大 Selector ... 监听所有注册通道,存在IO流操作是,会将对应的信息SelectionKey存入到内部的集 合中,参数是一个超时时间 public Set selectionKeys();
NIO完成网络编程 1. Selector——选择器老大 ... 监听所有注册通道,存在IO流操作是,会将对应的信息SelectionKey存入到内部的集合中,参数是一个超时时间 public Set selectionKeys(); 返回当前Se
选择器(Selectors) 选择键(SelectionKey) 示例:简易的客户端服务器通信 集合 集合框架总览 -、Iterator Iterable ListIterator 二、Map 和 Collection 接口Map 集合体系详解 HashMap LinkedHashMap TreeMap ...