JAVA NIO Selector 知识三
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA NIO Selector 知识三相关的知识,希望对你有一定的参考价值。
Selector(选择器)
Selector工作流程:我们把想要的soketchannel告诉selector后,我们就去可以做别的事情,当有事件发生的时候,selector会通知我们,然后获取selectionkey,获得我们感兴趣的事件。
selecotr是java nio多路复用的关键类,selector实现了一个线程管理多个channel,只需要更少的资源来处理更多的通道,节省线程之间的开销,这么说seletor是以前cpu很贵的时候,现在很多公司的机器都是多核,充分利用cpu才是最好的应用,后期会写些JAVA NIO的最佳实践netty。
下面写几个简单的例子:
Seletor的创建方式:
Selector selector = Selector.open();
channel注册到seletor上:
SelectionKey key = channel.register(selector,Selectionkey.OP_READ);
channel注册到Selector后会返回一个SelectionKey对象,SelectionKey代表着这个channel和注册的
selector的关系,SelectionKey维护着两个重要的属性interestOps和readyops。
Selector通常会监听四种类型的事件:
connect
accept
read
write
这四种事件通常用Selectionkey对应的一些:
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SELECTIONKEY.OP_READ
SELECTIONKEY.OP_WRITE
//打开服务器端的套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //服务器端设置为非阻塞 serverSocketChannel.configureBlocking(false); //服务端进行绑定 serverSocketChannel.bind(new InetSocketAddress("localhost", 8000)); //注册感兴趣的事件 Selector selector = Selector.open(); SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); selectionKey.* 可以查看一些感兴趣的事件
select()方法:
int selectCount = selector.select();阻塞到至少有一个再注册的通道上就绪了 selector.select(timeout);这个有超时时间 selector.selectNow();这个是到无论有没有都立马就返回了
selectedKeys()方法:
Set<SelectionKey> keys = selector.selectedKeys(); //获取迭代器 Iterator<SelectionKey> keyIterator = keys.iterator();
获取我我们需要的监听的事件;
while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (!key.isValid()) { continue; } if (key.isAcceptable()) { ServerSocketChannel sscTemp = (ServerSocketChannel) key.channel(); //得到一个连接好的SocketChannel,并把它注册到Selector上,兴趣操作为READ SocketChannel socketChannel = sscTemp.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); System.out.println("REGISTER CHANNEL , CHANNEL NUMBER IS:" + selector.keys().size()); } else if (key.isReadable()) { //读取通道中的数据 SocketChannel channel = (SocketChannel) key.channel(); read(channel); } keyIterator.remove(); //该事件已经处理,可以丢弃 }
以上是关于JAVA NIO Selector 知识三的主要内容,如果未能解决你的问题,请参考以下文章