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集合:关注事件中已经准备好的事件。方法:
int
readySet = 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.选择通道

    selector.select();

    该方法将堵塞,直到在selector上面注册的channel中有它感兴趣的事件发生。
  • 其他的重构方法:
  • select(long timeout)
  • selectNow()

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()方法上的线程会立马返回。

posted @ 2013-07-31 10:51  lxzh504  阅读(313)  评论(0编辑  收藏  举报