目录
-
- Selector是什么
- 如何创建一个Selector对象
- 如何将selectable channel注册到selector中
- selector如何维护selection keys
- selector如何选择就绪channel
- selector线程安全吗
- 原文
- Selection
- Concurrency
Selector是什么
- Selector是一个或多个SelectableChannel对象的多路复用器.
如何创建一个Selector对象
- 一个
对象可以通过调用Selector.open()来创建,这个工厂方法会使用系统默认的selector provider来创建一个新的selector对象。或者我们还可以通过实现抽象类selector
自定义一个selector provider,然后调用它的SelectorProvider
openSelector()
来创建,
例如:new SelectorProviderImpl().openSelector()
- 除非调用selector.close(),否则该
将会一直保持selector
。打开状态
如何将selectable channel注册到selector中
- 通过
的register方法,将channel
注册到给定的channel
中,并返回一个表示注册关系的SelectionKey 对象。selector
selector如何维护selection keys
一个
selector
维护着三个selection keys集合:
- key set 包含着所有
s,当前所有注册到selectionKey
中的selector
返回的注册关系SelectionKey都包含在内,这个集合可以通过selector.keys() 方法返回。channel
- selected-key set 包含着一部分
s,其中的每个selectionKey
所关联的selectionKey
在channel
期间被检测出至少selection operation
了一个可以在准备好
中匹配到的操作。这个集合可以通过调用selector.selectedKeys()方法返回。selected-key set 一定是 key set 的子集。兴趣集
- cancelled-key set 也包含着一部分
s,其中的每个selectionKey
都已经被selectionKey
,但是所关联取消
还没有被channel
。cancelled-key set 不能够被直接返回,但也一定是 key set 的子集。撤销登记
对于一个新创建的
selector
其中这三个集合都是空着的。
通过
channel
的register方法,一个
selectionKey
被增加到
selector
的 key set 中。
无论通过channel.close()还是通过selectionKey.cancel()来
取消
一个
selectionKey
,这个
selectionKey
都会被立即添加到
selector
的 cancelled-key set 中,但是所关联的
channel
并没有立即被
撤销登记
,直到发生下次
selection operations
, 这些
channel
才被从
selector
中
撤销登记
,与此同时这些Cancelled keys才会被从这个
selector
的所有
selectionKey set
(可能是_key set_、selected-key set、cancelled-key set)中移除,但是不会影响这些集合本身。
在
selection operations
期间,一些
selectionKey
会被选中添加到 selected-key set 中。其中的每个
key
可以通过selectiedKeys.remove()或selectiedKeys.iterator().remove()直接从 selected-key set 中移除,除此之外不能够通过任何方式被直接移除。特殊的,selected-key set 中的
keys
还可以在
selection operations
期间被间接移除。但是是不可以直接向 selected-key set 添加
key
的。
selector如何选择就绪channel
- 每次
期间, keys都可以添加到或从selector’s selected-key set 被移除,同时也可以从它的 key 和 cancelled-key sets 被移除。selection operation
可以被触发通过执行selector.select(),selector.select(long),和selector.selectNow() 方法,并且这些方法涉及到以下三个步骤:selection operation
- 首先每个位于 cancelled-key set 中的
会从每个包含它的
key
集合中被移除,并且对应的
key
会被
channel
。这个步骤使得 cancelled-key set 变为空。
撤销登记
- 查询底层操作系统来获得关于
中剩余
selector
的
channel
从
就续事件
开始截止到此刻的更新情况,只要哪个
selection operation
的
channel
有至少一个与
就续事件的更新部分
中的操作匹配上,那么将会执行以下两个动作:
兴趣集
如果这些
- 如果这个
channel's key
于 selected-key set 那么将它添加到这个集合中,并将它的
没有存在
(ready-operation set)修改成
就绪操作集
使得
只包含
被报告就绪的操作,任何先前记录在
channel
中的就绪信息都会被丢弃。
就绪操作集
- 否则,如果这个
channel's key
于 selected-key set ,那么就保留
存在
中先前的就绪信息,并将这些 使得
就绪操作集
被报告就绪的操作 写入进去;总而言之,系统底层会通过
channel
更新当前就绪集。
按位与&操作
的
Key
为空,那么 selected-key set 和 keys’的
兴趣集
(ready-operation sets)都不会被更新。
就续集
- 如果在步骤(2)正在进行时将任何
添加到 cancelled-key set,则按步骤(1)处理它们。
key
-
是否会阻塞等待一个或多个通道准备就绪,以及等待多长时间,这是三种选择方法之间唯一的本质区别。selection operations
selector线程安全吗
多线程并发情况下
Selectors
本身是线程安全的,但是他们所持有的
key sets
不是线程安全的。
selection operations
按顺序在
selector
本身,key set 和 selected-key set 上同步。 它们还在上面的步骤(1)和(3)期间在 canceled-key set 上同步。
在
selection operations
期间改变
key
的
兴趣集
,对于本次操作将不会产生任何影响;它们的影响将会在下次
selection operations
期间发生。
selectionKey
可能会被取消,
channel
可能随时关闭。 因此,在一个或多个选择器的
key集
中存在并不意味着
selectionKey
有效或其
channel
是开放的。有可能另一个线程取消
selectionKey
或关闭一个
channel
,应用程序代码应该小心地同步并检查这些条件。
一个线程通过selector.select()或selector.select(long)方法产生的阻塞可以被其他线程用以下三种方式的任意一种来中断:
- By invoking the selector’s wakeup() method,
- By invoking the selector’s close() method, or
- By invoking the blocked thread’s interrupt() method, in which case its interrupt status will be set and the selector’s wakeup() method will be invoked.
selector.close() 在
selection operations
期间会顺序的同步
selector
and
all three key sets
。
一个
selector
的 key set 和 selected-key set 通常情况下是线程不安全的。如果一个线程想要修改这个集合,需要同步控制它。通过
key集合
的iterator()方法返回的
Iterators
提供了
快速失败
(fail-fast):如果在创建迭代器之后修改了set,除了通过调用迭代器自己的remove() 方法之外,将抛出ConcurrentModificationException 。
原文
-
A multiplexor of SelectableChannel objects.
A selector may be created by invoking the
method of this class, which will use the system’s defaultopen
to create a new selector. A selector may also be created by invoking theselector provider
method of a custom selector provider. A selector remains open until it is closed via itsopenSelector
close
method.
A selectable channel’s registration with a selector is represented by a
object. A selector maintains three sets of selection keys:SelectionKey
- The key set contains the keys representing the current channel registrations of this selector. This set is returned by the
method.keys
- The selected-key set is the set of keys such that each key’s channel was detected to be ready for at least one of the operations identified in the key’s interest set during a prior selection operation. This set is returned by the
method. The selected-key set is always a subset of the key set.selectedKeys
- The cancelled-key set is the set of keys that have been cancelled but whose channels have not yet been deregistered. This set is not directly accessible. The cancelled-key set is always a subset of the key set.
All three sets are empty in a newly-created selector.
A key is added to a selector’s key set as a side effect of registering a channel via the channel’s
register
method. Cancelled keys are removed from the key set during selection operations. The key set itself is not directly modifiable.
A key is added to its selector’s cancelled-key set when it is cancelled, whether by closing its channel or by invoking its
cancel
method. Cancelling a key will cause its channel to be deregistered during the next selection operation, at which time the key will removed from all of the selector’s key sets.
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
method or by invoking theremove
method of anremove
obtained from the set. Keys are never removed from the selected-key set in any other way; they are not, in particular, removed as a side effect of selection operations. Keys may not be added directly to the selected-key set.iterator
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()
, andselect(long)
methods, and involves three steps:selectNow()
- Each key in the cancelled-key set is removed from each key set of which it is a member, and its channel is deregistered. This step leaves the cancelled-key set empty.
- The underlying operating system is queried for an update as to the readiness of each remaining channel to perform any of the operations identified by its key’s interest set as of the moment that the selection operation began. For a channel that is ready for at least one such operation, one of the following two actions is performed:
- If the channel’s key is
in the selected-key set then it is added to that set and its ready-operation set is modified to identify exactly those operations for which the channel is now reported to be ready. Any readiness information previously recorded in the ready set is discarded.not already
- Otherwise the channel’s key
in the selected-key set, so its ready-operation set is modified to identify any new operations for which the channel is reported to be ready. Any readiness information previously recorded in the ready set is preserved; in other words, the ready set returned by the underlying system is bitwise-disjoined into the key’s current ready set.is already
- If the channel’s key is
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.
3. If any keys were added to the cancelled-key set while step (2) was in progress then they are processed as in step (1).
Whether or not a selection operation blocks to wait for one or more channels to become ready, and if so for how long, is the only essential difference between the three selection methods.
Concurrency
Selectors are themselves safe for use by multiple concurrent threads; their key sets, however, are not.
The selection operations synchronize on the selector itself, on the key set, and on the selected-key set, in that order. They also synchronize on the cancelled-key set during steps (1) and (3) above.
Changes made to the interest sets of a selector’s keys while a selection operation is in progress have no effect upon that operation; they will be seen by the next selection operation.
Keys may be cancelled and channels may be closed at any time. Hence the presence of a key in one or more of a selector’s key sets does not imply that the key is valid or that its channel is open. Application code should be careful to synchronize and check these conditions as necessary if there is any possibility that another thread will cancel a key or close a channel.
A thread blocked in one of the
orselect()
methods may be interrupted by some other thread in one of three ways:select(long)
- By invoking the selector’s
method,wakeup
- By invoking the selector’s
method, orclose
- By invoking the blocked thread’s
method, in which case its interrupt status will be set and the selector’sinterrupt
method will be invoked.wakeup
close
method synchronizes on the selector and all three key sets in the same order as in a selection operation.
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’
methods are fail-fast: If the set is modified after the iterator is created, in any way except by invoking the iterator’s owniterator
method, then aremove
will be thrown.ConcurrentModificationException
- The key set contains the keys representing the current channel registrations of this selector. This set is returned by the