Selector
1.为什么使用selector?
selector是javaNIO中的能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。事实上,可以只用一个线程处理所有的通道。增加系统的吞吐量,提高服务性能。
2.selector的创建
selector的创建是通过静态方法open来进行创建一个系统默认配置的selector。也可通过调用自定义选择器提供程序的 openSelector
方法来创建选择器。通过选择器的 close
方法关闭选择器之前,它一直保持打开状态。
Selector selector = Selector.open();
3.通道的创建
Channel接口有2中实现类
文件Channel,socket channel两种
SocketChannel sc = SocketChannel.open();
sc.connect (new InetSocketAddress ("somehost", someport));
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind (new InetSocketAddress (somelocalport));
DatagramChannel dc = DatagramChannel.open();
RandomAccessFile raf = new RandomAccessFile ("somefile", "r");
FileChannel fc = raf.getChannel();
3.通道在selector的注册
channel.configureBlocking(
false
); //与selecotr一起使用时,channel必须是非阻塞的。
SelectionKey key = channel.register(selector,
Selectionkey.OP_READ);
4.关注事件的类型
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SelectionKey.OP_READ
SelectionKey.OP_WRITE
5.关于SelectionKey对象
- interest集合:已经关注的事件。方法:selectionKey.interestOps();
ready集合:关注事件中已经准备好的事件。方法:
intreadySet = selectionKey.readyOps();
也可以使用:
selectionKey.isAcceptable();
selectionKey.isConnectable();
selectionKey.isReadable();
selectionKey.isWritable()
- Channel:注册的通道。
Channel channel = selectionKey.channel();
- Selector:select对象。
Selector selector = selectionKey.selector();
- 附加的对象(可选):可以指定Handler对象。
selectionKey.attach(theObject);
Object attachedObj = selectionKey.attachment();
6.选择通道
- 其他的重构方法:
- select(long timeout)
- selectNow()
selector.select();
该方法将堵塞,直到在selector上面注册的channel中有它感兴趣的事件发生。7.selectedKeys()
Set selectedKeys = selector.selectedKeys();
遍历现在已经触发的事件。
Iterator keyIterator = selectedKeys.iterator();
while
(keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if
(key.isAcceptable()) {
}
else
if
(key.isConnectable()) {
}
else
if
(key.isReadable()) {
}
else
if
(key.isWritable()) {
}
keyIterator.remove();
}
8.WakeUp()
某个线程调用select()方法后阻塞了,即使没有通道已经就绪,也有办法让其从select()方法返回。只要让其它线程在第一个线程.
调用select()方法的那个对象上调用Selector.wakeup()方法即可。阻塞在select()方法上的线程会立马返回。