JAVA NIO Selector 知识四

本文详细介绍了Java NIO中Selector的使用方法及工作原理。包括Selector的创建、通道注册、事件监听等关键步骤。通过实例展示了如何利用Selector实现高效的多路复用。

Selector(选择器)


Selector工作流程:我们把想要的soketchannel告诉selector后,我们就去可以做别的事情,当有事件发生的时候,selector会通知我们,然后获取selectionkey,获得我们感兴趣的事件。


selecotr是java nio多路复用的关键类,selector实现了一个线程管理多个channel,只需要更少的资源来处理更多的通道,节省线程之间的开销,这么说seletor是以前cpu很贵的时候,现在很多公司的机器都是多核,充分利用cpu才是最好的应用,后期会写些JAVA NIO的最佳实践netty。


下面写几个简单的例子:

Seletor的创建方式:

1
Selector selector = Selector.open();


channel注册到seletor上:

1
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

1
2
3
4
5
6
7
8
9
10
11
//打开服务器端的套接字通道
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()方法:

1
2
3
            int selectCount = selector.select();阻塞到至少有一个再注册的通道上就绪了
            selector.select(timeout);这个有超时时间
            selector.selectNow();这个是到无论有没有都立马就返回了


selectedKeys()方法:
1
2
3
 Set<SelectionKey> keys = selector.selectedKeys();
            //获取迭代器
 Iterator<SelectionKey> keyIterator = keys.iterator();


获取我我们需要的监听的事件;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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 知识三 http://shangdc.blog.51cto.com/10093778/1956602
 
JAVA NIO buffer (知识三)
http://shangdc.blog.51cto.com/10093778/1956602
 
JAVA NIO 之 channel通道(知识二)
 
http://shangdc.blog.51cto.com/10093778/1955874
 
JAVA NIO 知识一
http://shangdc.blog.51cto.com/10093778/1955793


本文转自 豆芽菜橙 51CTO博客,原文链接:http://blog.51cto.com/shangdc/1956921
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值