Most visited

Recently visited

Added in API level 1

Selector

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对象。 选择器保持三组选择键:

在新创建的选择器中,所有三组都是空的。

通过通道的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方法或通过调用从该集合获得的 iteratorremove方法。 密钥永远不会以任何其他方式从选定密钥集中移除; 特别是它们不作为选择操作的副作用而被移除。 密钥可能不会直接添加到所选密钥集中。

Selection

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()方法,以及包括三个步骤:

  1. 取消密钥集中的每个密钥都从其所属的每个密钥集中移除,并且其信道被注销。 此步骤将取消密钥集留空。

  2. 查询底层操作系统的更新,以便关于每个剩余频道准备执行由选择操作开始时刻开始其密钥的兴趣集所标识的任何操作。 对于至少可以进行一次此类操作的通道,将执行以下两个操作之一:

    1. 如果通道的密钥尚未处于选定密钥集中,则会将其添加到该集中,并修改其准备好的操作集以准确标识现在报告通道准备就绪的那些操作。 先前记录在就绪集中的任何准备信息都被丢弃。

    2. 否则,通道的密钥已经在选定的密钥集中,因此其准备好的操作集被修改,以识别通道被报告准备就绪的任何新操作。 先前记录在就绪集合中的任何准备信息都被保留; 换句话说,由底层系统返回的就绪集按位分散到密钥的当前就绪集中。

  3. If all of the keys in the key set at the start of this step have empty interest sets then neither the selected-key set nor any of the keys' ready-operation sets will be updated.
  4. 如果在步骤(2)正在进行时将任何键添加到已取消键集中,则按照步骤(1)处理它们。

选择操作是否阻塞以等待一个或多个通道准备就绪,以及如果是这样多长时间,这三种选择方法之间唯一的本质区别。

Concurrency

选择器本身是安全的,可供多个并发线程使用; 但是,他们的钥匙套件却不是。

选择操作按照选择器本身,按键组和选定按键组的顺序进行同步。 他们还在上述步骤(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

也可以看看:

Summary

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

Protected constructors

Selector

Added in API level 1
Selector ()

初始化此类的新实例。

Public methods

close

Added in API level 1
void close ()

关闭此选择器。

如果一个线程目前被阻塞在此选择器的选择方法之一,那么它被中断,就好像通过调用选择器的 wakeup方法。

任何与该选择器相关的未被取消的密钥都将失效,其通道将被取消注册,并且释放与此选择器相关的任何其他资源。

如果此选择器已关闭,则调用此方法不起作用。

在选择器关闭之后,除了调用此方法或 wakeup方法之外,如果进一步尝试使用它,将导致抛出 ClosedSelectorException

Throws
IOException If an I/O error occurs

isOpen

Added in API level 1
boolean isOpen ()

判断这个选择器是否打开。

Returns
boolean true if, and only if, this selector is open

keys

Added in API level 1
Set<SelectionKey> keys ()

返回这个选择器的键集。

密钥集不能直接修改。 一个密钥只有在它被取消并且其频道已被注销后才被删除。 任何尝试修改密钥集都会导致UnsupportedOperationException被抛出。

密钥集是 not thread-safe

Returns
Set<SelectionKey> This selector's key set
Throws
ClosedSelectorException If this selector is closed

open

Added in API level 1
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

provider

Added in API level 1
SelectorProvider provider ()

返回创建此频道的提供商。

Returns
SelectorProvider The provider that created this channel

select

Added in API level 1
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

select

Added in API level 1
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

selectNow

Added in API level 1
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

selectedKeys

Added in API level 1
Set<SelectionKey> selectedKeys ()

返回此选择器的选定键集。

密钥可以从选定密钥集中移除,但不能直接添加到选定密钥集中。 任何尝试向键集添加对象都会导致UnsupportedOperationException被抛出。

选定的密钥集是 not thread-safe

Returns
Set<SelectionKey> This selector's selected-key set
Throws
ClosedSelectorException If this selector is closed

wakeup

Added in API level 1
Selector wakeup ()

导致尚未返回的第一个选择操作立即返回。

如果在调用select()select(long)方法时当前阻塞另一个线程,则该调用将立即返回。 如果当前没有选择操作正在进行,那么这些方法之一的下一次调用将立即返回,除非在此期间调用selectNow()方法。 在任何情况下,该调用返回的值可能都不为零。 随后的select()select(long)方法的调用将照常阻塞,除非在此期间再次调用此方法。

在两次连续的选择操作之间多次调用此方法的效果与仅调用一次效果相同。

Returns
Selector This selector

Hooray!