Java NIO 详解---NIO中的异步网络IO

本文详细介绍了Java NIO中的异步网络IO,包括Selector如何实现一个线程管理多个网络连接,如何注册和监听Channel事件,以及ServerSocketChannel和SocketChannel的使用。通过非阻塞的SocketChannel和Selector,可以实现高效的网络通信。
摘要由CSDN通过智能技术生成

前面的例子都是关于如何通过NIO操作文件读写的,我们知道BIO中的Socket、ServerSocket提供了网络通信的能力,在NIO中也有对应的模块提供了这种能力,并且具有更加强大的功能—通过异步非阻塞的数据读写实现一个线程监听多个连接的能力。
1)异步IO
所谓的异步IO是一种没有阻塞读写数据的方法。通常情况下,代码在调用read()方法时程序会阻塞直到又可以读取的数据;同样代码在写入数据的时候,代码会阻塞直到数据写入完成。而异步IO不会有这种阻塞,相反应用程序将注册自己感兴趣的IO事件—可读数据的到达、写入数据完成、新的连接的到来,当这些事情发生的时候系统将会通知应用程序;这样的好处之一就在于可以使用一个线程操操作多个IO而不用像传统程序那样同步的轮询或需要使用多个线程来处理。
2)Selector
Selector(选择器)是NIO中能够监听一到多个通道,并且知道这些通道是否为读写做好准备的组件,这样一个线程可以通过管理多个Channel,进而管理多个网络连接。使用一个线程管理多个网络连接的好处在于可以避免线程间切换的开销。
下面示范如何以一个Selector管理Channel。首先是Selector的建立:

//通过静态的open()方法得到一个Selector
Selector selector = Selector.open();

然后是向Selector注册一个ServerSocketChannel并监听连接事件

//对于监听的端口打开一个ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//注册到Selector的Channel必须设置为非阻塞模式,否则实现不了异步IO
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
InetSocketAddress address = new InetSocketAddress(8410);
serverSocket.bind(address);
//第二个参数是表明这个Channel感兴趣的事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

与Selector同时使用的Channel必须处于非阻塞模式,这意味着FileChannel不能用于Selector,因为它不能切换到非阻塞通道;而套接字通道都是可以的。
register的第二个参数表明了该Channel感兴趣的事件,具体的事件分为四个类型 1.Connect 2.Accept 3.Read 4.Write ,具体来说某个channel成功连接到另一个服务器称为“连接就绪”。一个server socket channel准备好接收新进入的连接称为“接收就绪”。一个有数据可读的通道可以说是“读就绪”。等待写数据的通道可以说是“写就绪”。这些事件可以用SelectionKey的四个常量来表示:

SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SelectionKey.OP_READ
SelectionKey.OP_WRITE

上面的Channel只是注册了一个事件,但实际上是可以同时注册多个事件的,比如可以像下面这样同时注册”接收就绪”和”读就绪”两个事件:

//使用"|"连接同时注册多个事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT|SelectionKey.OP_READ);

3) SelectionKey
上面向Selector注册Channel后返回了一个SelectionKey对象,这个对象包含了一些很有用的信息集:

interest集合
ready集合
Channel
Selector

interest集合即上面Channel注册时添加的感兴趣的事件集合,我们可以通过调用SelectionKey 的interestOps()方法得

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值