有关于Selector的使用,我们在之前的示例中就已经用到过了。当然,基本都是最简单的使用。而有关于Selector的其他API、SelectionKey的API,我们都没有详细介绍过。故单独列一篇,来说明下其使用。
1.Selector的创建与使用// 创建,创建比较简单,就是一句话,实际后面做了很多工作。
Selector selector = Selector.open();
// Selector.open
public static Selector open() throws IOException {
return SelectorProvider.provider().openSelector();
}
// SelectorProvider.provider()
public static SelectorProvider provider() {
synchronized (lock) {
if (provider != null)
return provider;
return AccessController.doPrivileged(
new PrivilegedAction() {
public SelectorProvider run() {
// 加载java.nio.channels.spi.SelectorProvider系统参数配置对应的Provider
if (loadProviderFromProperty())
return provider;
// SPI方式加载SelectorProvider实现类
if (loadProviderAsService())
return provider;
// 以上两种都没有,则返回默认provider。
// 笔者Windows系统下直接返回WindowsSelectorProvider
// 最终Selector为WindowsSelectorImpl
provider = sun.nio.ch.DefaultSelectorProvider.create();
return provider;
}
});
}
}
// 获取哪些已经准备好的channel数量。非阻塞,方法会立即返回
public abstract int selectNow() throws IOException;
// 同selectNow,会一直阻塞到有准备好的channel事件为止
public abstract int select() throws IOException;
// 同select(),会阻塞最多timeout毫秒后返回
public abstract int select(long timeout)
我们可以在使用中选择合适的select方法,避免长时间的线程阻塞。
1.2 wakeupSelector提供wakeup方法来唤醒阻塞在1.1中select方法中的线程。
/**
* Causes the first selection operation that has not yet returned to return
* immediately.
*
* If another thread is currently blocked in an invocation of the
* {@link #select()} or {@link #select(long)} methods then that invocation
* will return immediately. If no selection operation is currently in
* progress then the next invocation of one of these methods will return
* immediately unless the {@link #selectNow()} method is invoked in the
* meantime. In any case the value returned by that invocation may be
* non-zero. Subsequent invocations of the {@link #select()} or {@link
* #select(long)} methods will block as usual unless this method is invoked
* again in the meantime.
*
*
Invoking this method more than once between two successive selection
* operations has the same effect as invoking it just once.
*
* @return This selector
*/
public abstract Selector wakeup();
注解真的很全了。
如果当前线程阻塞在select方法上,则立即返回;
如果当前Selector没有阻塞在select方法上,则本次wakeup调用会在下一次select方法阻塞时生效;
1.3 closepublic abstract void close() throws IOException;
public abstract boolean isOpen();
当我们不再使用Selector时,需要调用close方法来释放掉其它占用的资源,并将所有相关的选择键设置为无效。
被close后的Selector则不能再使用。
同时提供了isOpen方法来检测Selector是否开启。
1.4 keys & selectedKeys// Returns this selector's key set.
public abstract Set keys();
// Returns this selector's selected-key set.
public abstract Set selectedKeys();
keys方法返回的是目前注册到Selector上的所有channel以及对应事件;
selectedKeys方法返回的是目前注册到Selector上的所有channel活跃的事件。返回的结果集的每个成员都被判定是已经准备好了。
故,我们之前一直使用的就是selectedKeys方法。
那么SelectionKey是什么呢?接着看。
2.SelectionKey// A token representing the registration of
// a {@link SelectableChannel} with a {@link Selector}.
public abstract class SelectionKey {
// 代表我们关注的4种事件
public static final int OP_READ = 1
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?


微信扫码登录