java nio selector readable_【原创】java NIO selector 学习笔记 一

能力有限,仅仅是自己看源码的一些笔记。

主要介绍 可选通道 和 选择器 选择键(SelectableChannel  和 Selector SelectionKey)

选择器(Selector) 选择器类管理着一个被注册的通道集合的信息和它们的就绪状态。通道是和选择器一起被注册的,并且使用选择器来更新通道的就绪状态。当这么做的时候,可以选择将被激发的线程挂起,直到有就绪的的通道。

可选通道 selectableChannel可以被注册到Selector对象上,一个通道可以被注册到多个选择器上,但是对于每个选择器而言只能被注册一次。而且只有继承了selectableChannel的类才能被注册到通道上,并且注册的Channel需要是非阻塞的。

选择键 选择键封装了特定的通道与特定的选择器的注册关系。

接下来结合socketChannel的代码一一介绍:

serverSocketChannel = ServerSocketChannel.open();

serverSocketChannel.socket().bind(new InetSocketAddress(port));

serverSocketChannel.configureBlocking(false);

selector = Selector.open();

while(true)

{

SocketChannel socketchannel =serverSocketChannel.accept();

if(socketchannel!=null)

{

System.out.println("收到连接");

socketchannel.configureBlocking(false);

socketchannel.register(selector, SelectionKey.OP_READ);

}

int num=selector.selectNow();

if(num>0)

{

Set selectedKeys = selector.selectedKeys();

Iterator keyItertor=selectedKeys.iterator();

while(keyItertor.hasNext())

{

SelectionKey key = (SelectionKey) keyItertor.next();

if(key.isReadable())

{

socketchannel = (SocketChannel) key.channel();

System.out.println(new String(buffer.array(),"utf-8"));

buffer.clear();

break;

}

}

}

}

首先获取一个Selector。获取selector只能使用Open方法。接下来我想说的是注册 register方法

Channel的register的源码 来自AbstractSelectableChannel

public final SelectionKey register(Selector sel, int ops,

Object att)

throws ClosedChannelException

{

if (!isOpen())

throw new ClosedChannelException();

if ((ops & ~validOps()) != 0)

throw new IllegalArgumentException();

synchronized (regLock) {

if (blocking)

throw new IllegalBlockingModeException();

SelectionKey k = findKey(sel);

if (k != null) {

k.interestOps(ops);

k.attach(att);

}

if (k == null) {

// New registration

k = ((AbstractSelector)sel).register(this, ops, att);

addKey(k);

}

return k;

}

}

当这个Channel已经在通道上注册了的话则更新 ops和att,否则调用AbstractSelector的register方法来注册。注意 Selector本身并没有register方法。

然后再看SelectorImp中的实现:

protected final SelectionKey register(AbstractSelectableChannel ch,

int ops,

Object attachment)

{

if (!(ch instanceof SelChImpl))

throw new IllegalSelectorException();

SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);

k.attach(attachment);

synchronized (publicKeys) {

implRegister(k);

}

k.interestOps(ops);

return k;

}

implRegister()的实现没找到。对于SPI不了解呀。

接下来介绍SelectionKey

介绍SelectionKeyImp

成员:

final SelChImpl channel; // package-private

final SelectorImpl selector; // package-private

// Index for a pollfd array in Selector that this key is registered with

private int index;

private volatile int interestOps;

private int readyOps;

和注册相关的方法:

public SelectionKey interestOps(int ops) {

ensureValid();

return nioInterestOps(ops);

}

SelectionKey nioInterestOps(int ops) { // package-private

if ((ops & ~channel().validOps()) != 0)

throw new IllegalArgumentException();

channel.translateAndSetInterestOps(ops, this);

interestOps = ops;

return this;

}

这一篇就到这吧。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值