美文网首页JavaJava学习笔记Java学习笔记
Java非阻塞IO NIO之Selector选择器

Java非阻塞IO NIO之Selector选择器

作者: taylar_where | 来源:发表于2019-05-26 15:54 被阅读0次

NIO自从JDK1.4版本以来就添加的一个非阻塞I/O框架,NIO是Java为解决网络通讯中高并发问题的一个类库,Selector是java NIO的一个组件,用于检查一个或多个NIO Channel的状态是否处于可读、可写。如此可以实现单线程管理多个channels,也就是可以管理多个网络链接,所以Selecotr是实现了多路复用的关键。

为什么要使用Selector呢?

用单线程处理多个channels的好处是我需要更少的线程来处理channel。实际上,你甚至可以用一个线程来处理所有的channels。从操作系统的角度来看,切换线程开销是比较昂贵的,并且每个线程都需要占用系统资源,因此使用的线程自然是越少越好。

需要留意的是,现代操作系统和CPU在多任务处理上已经变得越来越好,所以多线程带来的影响也越来越小。如果一个CPU是多核的,如果不执行多任务反而是浪费了机器的性能。不过这些设计讨论是另外的话题了。简而言之,通过Selector我们可以实现单线程操作多个channel。

这有一幅示意图,描述了单线程处理三个channel的情况:

图一

从图中我们可以看到,一个线程通过使用Selector可以同时管理3个Channel,那么如何实现这种管理的呢?我们先来看看Selector的定义:选择器(Selector)是SelectableChannle 对象的多路复用器,Selector 可以同时监控多个SelectableChannel 的IO 状况。不同于BIO(阻塞式I/O),Selector通过将channel注册到相应的集合中,在注册时使用一个SelectionKey来表示当前channel的状态,从而实现管理多个channel

创建一个selector的方法:

Selector selector=Selector.open();//创建一个Selector是通过Selector提供的open方法实现的。

注册Channel到Selector上,使得Selector可以管理Channel

channel.configureBlocking(false);  //将阻塞设置为非阻塞

SelectionKey key = channel.register(selector, SelectionKey.OP_READ); 

第一句代码是将channel转换为非阻塞模式,这一句是必不可少的,第二句代码在的使用方法有点反人类,按照我们的思维应该使用selector添加一个channel,但是代码中是将一个chanel注册到一个selector中,所以在编写代码是应该注意一下,这个时候我们能够发现第二个参数SelectionKey.OP_READ,这个表示了当前channel的状态,我们来看看SelectionKey提供的其他几种状态:

1.Connect   //此时处于“连接就绪”状态

2.Accept   //此时处于“可连接就绪”状态

3.Read      //此时处于“读就绪”状态

4.Write     //此时处于“写就绪”状态

这四种状态是用来表示channel的,在SelctionKey中他们分别对应:

1.SelectionKey.OP_CONNECT

2.SelectionKey.OP_ACCEPT

3.SelectionKey.OP_READ

4.SelectionKey.OP_WRITE

若注册时不止监听一个事件,则可以使用“位或”操作符连接。

channel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);

图二

看完了SelectionKey对象,我们再回过头来看看我们的Selector类,类中一个方法keys(),该方法返回的是一个SelectionKey类型的Set集合,该方法能够将所有状态为OP_CONNECT的SelectionKey集合,也就是返回所有接入Selector的channel,我们可以通过SelectionKey中的channel方法获得到Channel对象,这样的话,我们就获得了Seelectoe管理的所有Channel对象。有了这个对象我们自然可以完成很多东西,关于这方面的应用我就不多叙述了。

Selector提供了一个select()方法,该方法返回所有可用的channel数量。

Selector还提供了selectedKeys()方法,用于获得所有可用的channel。

关于其他方法大家有兴趣可以看JDK的源码进行深一步的了解。

参考文章:http://tutorials.jenkov.com/java-nio/selectors.html

相关文章

网友评论

    本文标题:Java非阻塞IO NIO之Selector选择器

    本文链接:https://www.haomeiwen.com/subject/pfoxtctx.html