public abstract class Selector
extends Object
implements Closeable
java.lang.Object | |
↳ | java.nio.channels.Selector |
Known Direct Subclasses |
一个 SelectableChannel
对象的多路复用器。
可以通过调用open
方法创建选择器,该方法将使用系统的默认 selector provider
来创建新的选择器。 选择器也可以通过调用自定义选择器提供程序的
openSelector
方法来创建。 选择器保持打开状态,直到它通过其close
方法关闭。
A selectable channel's registration with a selector is represented by a
SelectionKey
对象。 选择器保持三组选择键:
密钥集包含代表此选择器当前通道注册的密钥。 该组由keys
方法返回。
所选密钥集合是密钥集合 ,使得在先前的选择操作期间检测到每个密钥的信道准备好用于在密钥的兴趣集合中识别的至少一个操作。 该组由selectedKeys
方法返回。 所选密钥集始终是密钥集的子集。
已取消密钥集是已被取消但其通道尚未注销的密钥集。 这套不能直接访问。 取消密钥集始终是密钥集的一个子集。
在新创建的选择器中,所有三组都是空的。
通过通道的register
方法将一个键添加到选择器的键集中,作为注册频道的register
。 在选择操作期间取消的键将从键集中移除。 密钥集本身不能直接修改。
一个键被取消时添加到其选择器的取消键集中,无论是通过关闭其频道还是调用其cancel
方法。 取消密钥将导致其频道在下一次选择操作期间被注销,此时该密钥将从所有选择器的密钥集中移除。
Keys are added to the selected-key set by selection operations. A key may be removed directly from the selected-key set by invoking the set's
remove
方法或通过调用从该集合获得的 iterator
的
remove
方法。 密钥永远不会以任何其他方式从选定密钥集中移除; 特别是它们不作为选择操作的副作用而被移除。 密钥可能不会直接添加到所选密钥集中。
During each selection operation, keys may be added to and removed from a selector's selected-key set and may be removed from its key and cancelled-key sets. Selection is performed by the
select()
, select(long)
,并 selectNow()
方法,以及包括三个步骤:
取消密钥集中的每个密钥都从其所属的每个密钥集中移除,并且其信道被注销。 此步骤将取消密钥集留空。
查询底层操作系统的更新,以便关于每个剩余频道准备执行由选择操作开始时刻开始其密钥的兴趣集所标识的任何操作。 对于至少可以进行一次此类操作的通道,将执行以下两个操作之一:
如果通道的密钥尚未处于选定密钥集中,则会将其添加到该集中,并修改其准备好的操作集以准确标识现在报告通道准备就绪的那些操作。 先前记录在就绪集中的任何准备信息都被丢弃。
否则,通道的密钥已经在选定的密钥集中,因此其准备好的操作集被修改,以识别通道被报告准备就绪的任何新操作。 先前记录在就绪集合中的任何准备信息都被保留; 换句话说,由底层系统返回的就绪集按位分散到密钥的当前就绪集中。
如果在步骤(2)正在进行时将任何键添加到已取消键集中,则按照步骤(1)处理它们。
选择操作是否阻塞以等待一个或多个通道准备就绪,以及如果是这样多长时间,这三种选择方法之间唯一的本质区别。
选择器本身是安全的,可供多个并发线程使用; 但是,他们的钥匙套件却不是。
选择操作按照选择器本身,按键组和选定按键组的顺序进行同步。 他们还在上述步骤(1)和(3)中的取消密钥集上进行同步。
选择操作正在进行时对选择器按键的兴趣集所做的更改对该操作没有影响; 他们将在下一次选择操作中看到。
密钥可能会被取消,频道可能随时关闭。 因此,在一个或多个选择器密钥集中存在密钥并不意味着密钥是有效的或者其信道是开放的。 如果有可能另一个线程将取消一个键或关闭一个通道,则应用程序代码应该小心地同步并根据需要检查这些条件。
在 select()
或 select(long)
方法之一中阻塞的线程可能会被其他线程以三种方式之一中断:
close
方法在选择器和所有三个按键集上按照与选择操作相同的顺序进行同步。
A selector's key and selected-key sets are not, in general, safe for use by multiple concurrent threads. If such a thread might modify one of these sets directly then access should be controlled by synchronizing on the set itself. The iterators returned by these sets'
iterator
方法是 快速失败的:如果在创建迭代器后修改了集合,除了调用迭代器自己的 remove
方法之外, remove
方法都会抛出 ConcurrentModificationException
。
也可以看看:
Protected constructors |
|
---|---|
Selector() 初始化此类的新实例。 |
Public methods |
|
---|---|
abstract void |
close() 关闭此选择器。 |
abstract boolean |
isOpen() 判断这个选择器是否打开。 |
abstract Set<SelectionKey> |
keys() 返回这个选择器的键集。 |
static Selector |
open() 打开选择器。 |
abstract SelectorProvider |
provider() 返回创建此频道的提供商。 |
abstract int |
select(long timeout) 选择一组键,其相应通道已准备好进行I / O操作。 |
abstract int |
select() 选择一组键,其相应通道已准备好进行I / O操作。 |
abstract int |
selectNow() 选择一组键,其相应通道已准备好进行I / O操作。 |
abstract Set<SelectionKey> |
selectedKeys() 返回此选择器的选定键集。 |
abstract Selector |
wakeup() 导致尚未返回的第一个选择操作立即返回。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
|
From interface java.io.Closeable
|
|
From interface java.lang.AutoCloseable
|
void close ()
关闭此选择器。
如果一个线程目前被阻塞在此选择器的选择方法之一,那么它被中断,就好像通过调用选择器的 wakeup
方法。
任何与该选择器相关的未被取消的密钥都将失效,其通道将被取消注册,并且释放与此选择器相关的任何其他资源。
如果此选择器已关闭,则调用此方法不起作用。
在选择器关闭之后,除了调用此方法或 wakeup
方法之外,如果进一步尝试使用它,将导致抛出 ClosedSelectorException
。
Throws | |
---|---|
IOException |
If an I/O error occurs |
boolean isOpen ()
判断这个选择器是否打开。
Returns | |
---|---|
boolean |
true if, and only if, this selector is open |
Set<SelectionKey> keys ()
返回这个选择器的键集。
密钥集不能直接修改。 一个密钥只有在它被取消并且其频道已被注销后才被删除。 任何尝试修改密钥集都会导致UnsupportedOperationException
被抛出。
密钥集是 not thread-safe 。
Returns | |
---|---|
Set<SelectionKey> |
This selector's key set |
Throws | |
---|---|
ClosedSelectorException |
If this selector is closed |
Selector open ()
打开选择器。
The new selector is created by invoking the openSelector
method of the system-wide default SelectorProvider
object.
Returns | |
---|---|
Selector |
A new selector |
Throws | |
---|---|
IOException |
If an I/O error occurs |
SelectorProvider provider ()
返回创建此频道的提供商。
Returns | |
---|---|
SelectorProvider |
The provider that created this channel |
int select (long timeout)
选择一组键,其相应通道已准备好进行I / O操作。
此方法执行阻止selection operation 。 它仅返回之后的至少一个信道被选择,此选择器的wakeup
方法被调用时,当前线程被中断,或者给定的超时期满,以先到者为准。
此方法不提供实时保证:它调度超时,就像调用 wait(long)
方法一样。
Parameters | |
---|---|
timeout |
long : If positive, block for up to timeout milliseconds, more or less, while waiting for a channel to become ready; if zero, block indefinitely; must not be negative |
Returns | |
---|---|
int |
The number of keys, possibly zero, whose ready-operation sets were updated |
Throws | |
---|---|
IOException |
If an I/O error occurs |
ClosedSelectorException |
If this selector is closed |
IllegalArgumentException |
If the value of the timeout argument is negative |
int select ()
选择一组键,其相应通道已准备好进行I / O操作。
此方法执行阻止selection operation 。 只有在选择了至少一个通道后,才会返回该选择器的方法wakeup
,或者当前线程中断,以先到者为准。
Returns | |
---|---|
int |
The number of keys, possibly zero, whose ready-operation sets were updated |
Throws | |
---|---|
IOException |
If an I/O error occurs |
ClosedSelectorException |
If this selector is closed |
int selectNow ()
选择一组键,其相应通道已准备好进行I / O操作。
此方法执行非阻塞selection operation 。 如果自上次选择操作以来没有通道可选,则此方法立即返回零。
调用此方法将清除以前任何调用 wakeup
方法的效果。
Returns | |
---|---|
int |
The number of keys, possibly zero, whose ready-operation sets were updated by the selection operation |
Throws | |
---|---|
IOException |
If an I/O error occurs |
ClosedSelectorException |
If this selector is closed |
Set<SelectionKey> selectedKeys ()
返回此选择器的选定键集。
密钥可以从选定密钥集中移除,但不能直接添加到选定密钥集中。 任何尝试向键集添加对象都会导致UnsupportedOperationException
被抛出。
选定的密钥集是 not thread-safe 。
Returns | |
---|---|
Set<SelectionKey> |
This selector's selected-key set |
Throws | |
---|---|
ClosedSelectorException |
If this selector is closed |
Selector wakeup ()
导致尚未返回的第一个选择操作立即返回。
如果在调用select()
或select(long)
方法时当前阻塞另一个线程,则该调用将立即返回。 如果当前没有选择操作正在进行,那么这些方法之一的下一次调用将立即返回,除非在此期间调用selectNow()
方法。 在任何情况下,该调用返回的值可能都不为零。 随后的select()
或select(long)
方法的调用将照常阻塞,除非在此期间再次调用此方法。
在两次连续的选择操作之间多次调用此方法的效果与仅调用一次效果相同。
Returns | |
---|---|
Selector |
This selector |