Java NIO 选择器

Selector是Java NIO中的一个组件,可以用来检查一个或多个通道,并确定哪一个通道准备好了读或写。通过这种方式,我们可以使用单个线程管理多个通道或多个网络连接。

为什么使用Selector?

使用Selector的优势在于你可以使用单个线程处理多个通道。实际上,你仅使用一个线程就可以处理所有的通道。线程切换对操作系统来说代价是昂贵的,并且每个线程在OS中都要占用一定的资源(内存)。因此,使用的线程越少越好。

请记住,现代操作系统和CPU对多任务的支持越来越好,多线程的时间开销越来越小。实际上,如果一个CPU有多个内核,你并不是因为多任务而浪费了CPU功耗。无论如何,在不同的文章中有不同的观点,这里我们可以说的是,你可以使用Selector来实现单个线程处理多个通道的目的。

下面是使用一个Selector处理3个通道的例子

创建一个Selector

你可以通过调用Selector.open()来创建一个Selector

Selector selector = Selector.open();

注册通道到选择器

为了使用一个Channel和一个Selector,你必须注册通道到Selector我们可以使用SelectableChannel.register()方法,像这样

<div style="text-align: center;"><span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">channel.configureBlocking(false);</span></div>
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);

通道必须处于非阻塞模式才能使用Selector。这意味对于FileChannel你不能使用Selector,因为FileChannel不能切换到非阻塞模式。SocketChannel不存在这样的问题。

需要注意的是register()的第二个参数,这是“interest set”,是指你对selector在channnel上监听什么类型的事件感兴趣。你可以监听以下四种类型的事件:

Connect

Accept

Read

Write

` A channel that "fires an event" is also said to be "ready" for that event。因此,一个通道成功连接到另外一个服务器就是“connect ready”。一个服务器端Socket接收一个入站连接就是“accept ready”。一个通道有数据可读就是“read ready”,一个通道准备好向其写入数据就是“write ready”。

我们用SelectionKey的四个常量来表示这四个事件:

如果你对多个事件感兴趣,你可以将读个常量放在一起,像这样:

int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

SelectionKey's

上面的小节我们提到,当我们使用register注册通道到一个Selector上的时候,将会返回一个SelectionKey对象。这个SelectionKey对象,包含一些令人感兴趣的属性:

The interest set

The ready set

The Channel

The Selector

An attached object(options)

下面我们一一讨论这些属性:

Interest Set

The interest set是你感兴趣"selecting"的事件集合。你可以像下面这样通过SelectionKey读写这些interest set:

int interestSet = selectionKey.interestOps();

boolean isInterestedInAccept  = interestSet & SelectionKey.OP_ACCEPT;
boolean isInterestedInConnect = interestSet & SelectionKey.OP_CONNECT;
boolean isInterestedInRead    = interestSet & SelectionKey.OP_READ;
boolean isInterestedInWrite   = interestSet & SelectionKey.OP_WRITE;   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值