【问题标题】:Java: Is SelectionKey.attach() broken?Java:SelectionKey.attach() 坏了吗?
【发布时间】:2010-11-21 13:22:19
【问题描述】:

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

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

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

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

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

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

谢谢!

【问题讨论】:

    标签: java nio nonblocking


    【解决方案1】:

    您的链接页面中没有 CR,我在 bugs.sun.com 上看不到任何内容。然而,attach/attachment 是非常简单的代码(虽然在我的bug 之后稍微复杂一些。我猜你得到的是不同的SelectionKey,所以试图包装它是没有意义的。

    【讨论】:

      【解决方案2】:

      我已经成功地将对象附加到 SelectionKeys 没有任何问题,但仅来自同一事件。例如,当我第一次获得OP_READ 时,我将一个对象附加到 SelectionKey 并在随后的读取中检索它,它工作正常。也许OP_ACCEPTOP_READ 处理不同的键,因为它们是不同的事件,但我认为对于同一个连接,SelectionKey 应该是相同的......但是如果你即使从同一个 IP 进行不同的连接,你也会得到不同的 SelectionKey .

      更新:我刚刚检查了我的代码,有一些非常重要的事情:我根本没有调用 attach();我使用了 SelectableChannel.register(Selector sel, int ops, Object att) 方法。如果您这样做,后续对 SelectionKey 上的 attachment() 的调用将起作用。

      【讨论】:

      • 非常感谢!我认为您提到的事物的组合可能会导致每次都有效的解决方案! :) 另外,如果附件()失败,我仍然可以选择进行更昂贵的地图查找,因此即使附件丢失,我也可以将其编写为健壮的!谢谢!
      • 这非常方便。我能够从我的 NIO 实现中删除一个 HashMap。谢谢!
      • 感谢您的回答。为我节省了很多时间。
      猜你喜欢
      • 2021-12-31
      • 2015-03-04
      • 2016-09-08
      • 2011-07-14
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多