Java:SelectionKey.attach() 损坏了吗?

问题描述 投票:0回答:2

在我的 Java NIO 实现中,我无法让 SelectionKey.attach() 工作。基本上,一旦客户端连接(OP_ACCEPT 兴趣操作),我将它们添加到映射中,其中它们的 IP 地址映射到维护客户端状态的对象。然后,当 OP_READ 发生时,我再次检索客户端的 IP 地址,这次从映射中获取值并以这种方式获取客户端的状态对象。

这里的问题是每次从网络读取数据时我都必须进行地图查找。那里有很多浪费的工作。因此,我很高兴看到您可以将任意对象类型附加到 SelectionKey,当您调用 SelectionKey.attachment() 时应该可以轻松检索该对象类型,即使我们现在正在处理不同的事件(在 OP_READ 期间检索与放入OP_ACCEPT 期间的地图)。

问题是它不起作用。当我检索附件时,它始终为空。如果我通过 Attach() 设置附件,然后立即调用 Attachment(),它就会起作用。不知何故,在不同的事件之间,它失去了关联。

抱歉,我的代码有点长,无法发布到这里,但是如果您查看此线程中的评论: 链接文字 ...你会发现其他一些人基本上得出了相同的结论:attach() 和attachment() 不起作用,而且从来没有起作用。

是否有一个技巧可以让它工作,或者我是否陷入了每次有新的读取事件需要处理时在地图中手动进行查找所必需的邪恶开销?

最后,有没有办法将 SelectionKey “包装”在一个新的子类中,以正确处理 Attach() 和 Attach() ?

谢谢!

java nio nonblocking
2个回答
6
投票

我已成功将对象附加到 SelectionKeys,没有任何问题,但仅来自同一事件。例如,第一次获得

OP_READ
时,我将一个对象附加到 SelectionKey,并在后续读取时检索它,并且效果很好。也许
OP_ACCEPT
OP_READ
处理不同的键,因为它们是不同的事件,但我认为对于同一连接,SelectionKey 应该是相同的...但是,如果您即使从同一 IP 建立不同的连接,您也会得到不同的 SelectionKey .

更新:我刚刚检查了我的代码,有一些非常重要的事情:我根本没有调用attach();我用的是

 SelectableChannel.register(Selector sel, int ops, Object att)
方法。如果这样做,后续对 SelectionKey 上的 Attachment() 的调用将会起作用。


1
投票

您的链接页面中没有 CR,我在 Java Bug Database 中看不到任何内容。然而,

attach
/
attachment
是非常简单的代码(尽管在我的bug之后稍微复杂一些。我的猜测是你得到了不同的
SelectionKey
,所以尝试包装它是毫无意义的。

© www.soinside.com 2019 - 2024. All rights reserved.