Selector API用法
java.nio.channels
类 Selector
java.lang.Object
java.nio.channels.Selector
- 直接已知子类:
- AbstractSelector
public abstract class Selectorextends Object
SelectableChannel 对象的多路复用器。
可通过调用此类的 open 方法创建选择器,该方法将使用系统的默认选择器提供者创建新的选择器。也可通过调用自定义选择器提供者的 openSelector 方法来创建选择器。通过选择器的 close 方法关闭选择器之前,它一直保持打开状态。
通过 SelectionKey 对象来表示可选择通道到选择器的注册。选择器维护了三种选择键集:
键集 包含的键表示当前通道到此选择器的注册。此集合由 keys 方法返回。
已选择键集 是这样一种键的集合,即在前一次选择操作期间,检测每个键的通道是否已经至少为该键的相关操作集所标识的一个操作准备就绪。此集合由 selectedKeys 方法返回。已选择键集始终是键集的一个子集。
已取消键集 是已被取消但其通道尚未注销的键的集合。不可直接访问此集合。已取消键集始终是键集的一个子集。
在新创建的选择器中,这三个集合都是空集合。
通过某个通道的 register 方法注册该通道时,所带来的副作用是向选择器的键集中添加了一个键。在选择操作期间从键集中移除已取消的键。键集本身是不可直接修改的。
不管是通过关闭某个键的通道还是调用该键的 cancel 方法来取消键,该键都被添加到其选择器的已取消键集中。取消某个键会导致在下一次选择操作期间注销该键的通道,而在注销时将从所有选择器的键集中移除该键。
通过选择操作将键添加到已选择键集中。可通过调用已选择键集的 remove 方法,或者通过调用从该键集获得的 iterator 的 remove 方法直接移除某个键。通过任何其他方式从不会将键从已选择键集中移除;特别是,它们不会因为影响选择操作而被移除。不能将键直接添加到已选择键集中。
选择
在每次选择操作期间,都可以将键添加到选择器的已选择键集以及从中将其移除,并且可以从其键集和已取消键集中将其移除。选择是由 select()、select(long) 和 selectNow() 方法执行的,执行涉及三个步骤:
将已取消键集中的每个键从所有键集中移除(如果该键是键集的成员),并注销其通道。此步骤使已取消键集成为空集。
在开始进行选择操作时,应查询基础操作系统来更新每个剩余通道的准备就绪信息,以执行由其键的相关集合所标识的任意操作。对于已为至少一个这样的操作准备就绪的通道,执行以下两种操作之一:
如果该通道的键尚未在已选择键集中,则将其添加到该集合中,并修改其准备就绪操作集,以准确地标识那些通道现在已报告为之准备就绪的操作。丢弃准备就绪操作集中以前记录的所有准备就绪信息。
如果该通道的键已经在已选择键集中,则修改其准备就绪操作集,以准确地标识所有通道已报告为之准备就绪的新操作。保留准备就绪操作集以前记录的所有准备就绪信息;换句话说,基础系统所返回的准备就绪操作集是和该键的当前准备就绪操作集按位分开 (bitwise-disjoined) 的。
如果在此步骤开始时键集中的所有键都有空的相关集合,则不会更新已选择键集和任意键的准备就绪操作集。
如果在步骤 (2) 的执行过程中要将任意键添加到已取消键集中,则处理过程如步骤 (1)。
是否阻塞选择操作以等待一个或多个通道准备就绪,如果这样做的话,要等待多久,这是三种选择方法之间的唯一本质差别。
并发性
选择器自身可由多个并发线程安全使用,但是其键集并非如此。
选择操作在选择器本身上、在键集上和在已选择键集上是同步的,顺序也与此顺序相同。在执行上面的步骤 (1) 和 (3) 时,它们在已取消键集上也是同步的。
在执行选择操作的过程中,更改选择器键的相关集合对该操作没有影响;进行下一次选择操作才会看到此更改。
可在任意时间取消键和关闭通道。因此,在一个或多个选择器的键集中出现某个键并不意味着该键是有效的,也不意味着其通道处于打开状态。如果存在另一个线程取消某个键或关闭某个通道的可能性,那么应用程序代码进行同步时应该小心,并且必要时应该检查这些条件。
阻塞在 select() 或 select(long) 方法之一中的某个线程可能被其他线程以下列三种方式之一中断:
通过调用选择器的 wakeup 方法,
通过调用选择器的 close 方法,或者
在通过调用已阻塞线程的 interrupt 方法的情况下,将设置其中断状态并且将调用该选择器的 wakeup 方法。
close 方法在选择器上是同步的,并且所有三个键集都与选择操作中的顺序相同。
一般情况下,选择器的键和已选择键集由多个并发线程使用是不安全的。如果这样的线程可以直接修改这些键集之一,那么应该通过对该键集本身进行同步来控制访问。这些键集的 iterator 方法所返回的迭代器是快速失败 的:如果在创建迭代器后以任何方式(调用迭代器自身的 remove 方法除外)修改键集,则会抛出 ConcurrentModificationException。
- 从以下版本开始:
- 1.4
- 另请参见:
- SelectableChannel, SelectionKey
构造方法摘要 | |
---|---|
protected |
Selector() 初始化此类的一个新实例。 |
方法摘要 | |
---|---|
abstract void |
close() 关闭此选择器。 |
abstract boolean |
isOpen() 告知此选择器是否已打开。 |
abstract Set<SelectionKey> |
keys() 返回此选择器的键集。 |
static Selector |
open() 打开一个选择器。 |
abstract SelectorProvider |
provider() 返回创建此通道的提供者。 |
abstract int |
select() 选择一组键,其相应的通道已为 I/O 操作准备就绪。 |
abstract int |
select(long timeout) 选择一组键,其相应的通道已为 I/O 操作准备就绪。 |
abstract Set<SelectionKey> |
selectedKeys() 返回此选择器的已选择键集。 |
abstract int |
selectNow() 选择一组键,其相应的通道已为 I/O 操作准备就绪。 |
abstract Selector |
wakeup() 使尚未返回的第一个选择操作立即返回。 |
从类 java.lang.Object 继承的方法 |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
构造方法详细信息 |
---|
Selector
protected Selector()
- 初始化此类的一个新实例。
方法详细信息 |
---|
open
public static Selector open()
throws IOException
- 打开一个选择器。
通过调用系统级默认 SelectorProvider 对象的 openSelector 方法来创建新的选择器。
-
- 返回:
- 新的选择器
- 抛出:
IOException
- 如果发生 I/O 错误
isOpen
public abstract boolean isOpen()
- 告知此选择器是否已打开。
-
- 返回:
- 当且仅当此选择器已打开时才返回 true
provider
public abstract SelectorProvider provider()
- 返回创建此通道的提供者。
-
- 返回:
- 创建此通道的提供者
keys
public abstract Set<SelectionKey> keys()
- 返回此选择器的键集。
不可直接修改键集。仅在已取消某个键并且已注销其通道后才移除该键。试图修改键集会导致抛出 UnsupportedOperationException。
键集是非线程安全的。
-
- 返回:
- 此选择器的键集
- 抛出:
ClosedSelectorException
- 如果此选择器已关闭
selectedKeys
public abstract Set<SelectionKey> selectedKeys()
- 返回此选择器的已选择键集。
可从已选择键集中移除键,但是无法直接添加键。试图向该键集中添加对象会导致抛出 UnsupportedOperationException。
已选择键集是非线程安全的。
-
- 返回:
- 此选择器的已选择键集
- 抛出:
ClosedSelectorException
- 如果此选择器已关闭
selectNow
public abstract int selectNow()
throws IOException
- 选择一组键,其相应的通道已为 I/O 操作准备就绪。
此方法执行非阻塞的选择操作。如果自从前一次选择操作后,没有通道变成可选择的,则此方法直接返回零。
调用此方法会清除所有以前调用 wakeup 方法所得的结果。
-
- 返回:
- 由选择操作更新其准备就绪操作集的键的数目,该数目可能为零
- 抛出:
IOException
- 如果发生 I/O 错误ClosedSelectorException
- 如果此选择器已关闭
select
public abstract int select(long timeout)
throws IOException
- 选择一组键,其相应的通道已为 I/O 操作准备就绪。
此方法执行处于阻塞模式的选择操作。仅在至少选择一个通道、调用此选择器的 wakeup 方法、当前的线程已中断,或者给定的超时期满(以先到者为准)后此方法才返回。
此方法不提供实时保证:它安排了超时时间,就像调用 Object.wait(long) 方法一样。
-
- 参数:
timeout
- 如果为正,则在等待某个通道准备就绪时最多阻塞 timeout 毫秒;如果为零,则无限期地阻塞;必须为非负数- 返回:
- 已更新其准备就绪操作集的键的数目,该数目可能为零
- 抛出:
IOException
- 如果发生 I/O 错误ClosedSelectorException
- 如果此选择器已关闭IllegalArgumentException
- 如果 timeout 参数的值为负
select
public abstract int select()
throws IOException
- 选择一组键,其相应的通道已为 I/O 操作准备就绪。
此方法执行处于阻塞模式的选择操作。仅在至少选择一个通道、调用此选择器的 wakeup 方法,或者当前的线程已中断(以先到者为准)后此方法才返回。
-
- 返回:
- 已更新其准备就绪操作集的键的数目,该数目可能为零
- 抛出:
IOException
- 如果发生 I/O 错误ClosedSelectorException
- 如果此选择器已关闭
wakeup
public abstract Selector wakeup()
- 使尚未返回的第一个选择操作立即返回。
如果另一个线程目前正阻塞在 select() 或 select(long) 方法的调用中,则该调用将立即返回。如果当前未进行选择操作,那么在没有同时调用 selectNow() 方法的情况下,对上述方法的下一次调用将立即返回。在任一情况下,该调用返回的值可能是非零的。如果未同时再次调用此方法,则照常阻塞 select() 或 select(long) 方法的后续调用。
在两个连续的选择操作之间多次调用此方法与只调用一次的效果相同。
-
- 返回:
- 此选择器
close
public abstract void close()
throws IOException
- 关闭此选择器。
如果某个线程目前正阻塞在此选择器的某个选择方法中,则中断该线程,如同调用该选择器的 wakeup 方法那样。
所有仍与此选择器关联的未取消键已无效、其通道已注销,并且与此选择器关联的所有其他资源已释放。
如果此选择器已经关闭,则调用此方法无效。
关闭选择器后,除了调用此方法或 wakeup 方法外,以任何其他方式继续使用它都将导致抛出 ClosedSelectorException。
-
- 抛出:
IOException
- 如果发生 I/O 错误
Selector API用法的更多相关文章
- 关于javascript dom扩展:Selector API
众多javascript库中最常用的一项功能,就是根据css选择符选择与某个模式匹配的DOM元素.之前由于对javascript的认识较低,对javascript对DOM操作还停留在getElemen ...
- SEL数据类型,@selector的用法,以及调用SEL
1.SEL数据类型 SEL是个指针类型的数据,类似C语言中的函数指针.在OC中,每个对象方法都有其对应着一个SEL变量.当我们调用对象方法时,编译器会将该方法转换成一个SEL的数据,然后去类中寻找该方 ...
- Hadoop生态圈-zookeeper的API用法详解
Hadoop生态圈-zookeeper的API用法详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.测试前准备 1>.开启集群 [yinzhengjie@s101 ~] ...
- Android中Selector的用法(改变ListView和Button的默认背景)
Android中的Selector的用法 http://blog.csdn.net/shakespeare001/article/details/7788400#comments Android中的S ...
- JavaEE基础(02):Servlet核心API用法详解
本文源码:GitHub·点这里 || GitEE·点这里 一.核心API简介 1.Servlet执行流程 Servlet是JavaWeb的三大组件之一(Servlet.Filter.Listener) ...
- <自动化测试>之<selenium API 用法2>
不知道之前的selenium API 用法1,有没有去练习, 个人认为线性代码还是要靠敲的, 后面的模块化除了多敲还需要一定的编程思想去理解, 今天下午不是很忙就给来这儿补充点selenium api ...
- TensorFlow Keras API用法
TensorFlow Keras API用法 Keras 是与 TensorFlow 一起使用的更高级别的作为后端的 API.添加层就像添加一行代码一样简单.在模型架构之后,使用一行代码,可以编译和拟 ...
- FFmpeg原始帧处理-滤镜API用法详解
本文为作者原创,转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10429145.html 在FFmpeg中,滤镜(filter)处理的是未压缩的原始音视频 ...
- Elasticsearch批量操作API用法介绍
Elasticsearch的Bulk API允许批量提交index和delete请求,有如下两种用法: 用法1 BulkRequestBuilder requestBuilder = client.p ...
随机推荐
- WdatePicker日期控件的使用
将压缩包中的文件连带文件夹添加到项目中去,注意要完整的添加到项目中去,不要更改了其目录结构 然后在aspx页面中直接使用即可: 首先引入: <script src="/Controls ...
- 洛谷P1316 丢瓶盖
题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...
- Vue 的 createElement 函数的参数问题的小笔记
官方文档的说明. 第二个参数的值是要生成的标签的属性数据.点击查看详情. 第三个参数则是组件标签内的数据,数据里面的内容会渲染在第一个参数的标签内.通常会在此指定各插槽 slot 对应的位置,也可以在 ...
- 【AIM Tech Round 4 (Div. 2) C】Sorting by Subsequences
[链接]http://codeforces.com/contest/844/problem/C [题意] 水题,没有记录意义 [题解] 排序之后,记录每个数字原来在哪里就好. 可以形成环的. 环的个数 ...
- linux下多进程的文件拷贝与进程相关的一些基础知识
之前实现了用文件IO的方式能够实现文件的拷贝,那么对于进程而言,我们是否也能够实现呢? 答案是肯定的. 进程资源: 首先我们先回想一下,进程的执行须要哪些资源呢?其资源包含CPU资源,内存资源,当然还 ...
- 1.12 Python基础知识 - 序列:字符串
字符串是一个有序的字符集合,即字符序列.Pythpn内置数据类型str,用于字符串处理,使用单引号或双引号括起来的字符,就是字符常量,Python解释器会自动创建str型对象实例. 字符串的定义: 1 ...
- AndroidStudio MAT LeakCanary 内存分析之 LeakCanary
现在我们换一种更清晰方便的方式:LeakCanary https://github.com/square/leakcanary 首先将LeakCanary绑在我们的app上 build.gradle ...
- Django模板变量,过滤器和静态文件引用
模版路径查找 首先去settings.py里面找TEMPLATES ,在TEMPLATES下面找DIRS,找到就返回,没找到就继续往下,如果APP_DIRS设置为为Ture,那么就会到上面 INSTA ...
- sampleviewer add menu item error 'assert'
可以跟踪到 mfc提供的源代码内部,(注:如果打开了mfc源代码,设置了断点,但是跟不进去,那就需要更新PDB文件,具体网上搜)打开 wincore.cpp文件(D:\Program Files\Mi ...
- POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)
依据题意可构造出方程组.方程组的每一个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki; 高斯消元构造上三角矩阵,以最后一个一行为例: C*x9 = ...