【问题标题】:Java NIO Selector.open() IOExceptionJava NIO Selector.open() IOException
【发布时间】:2014-01-10 22:28:06
【问题描述】:

在使用java.nio.channels.Selector 对象时,我不禁注意到工厂创建方法Selector.open() 抛出了一个IOException。

除了处理另一个 IOException 很痛苦之外,我不明白打开选择器可能是一个 I/O 操作,更不用说以某种方式失败并抛出一个 IOException。

要打开的Selector类里面的代码如下:

public static Selector open() throws IOException {
    return SelectorProvider.provider().openSelector();
}

注意到它遵循SelectorProvider 对象,我去看了openSelector() 的代码。如下:

public abstract AbstractSelector openSelector()
    throws IOException;

看起来类是在运行时动态加载的,这让这些选择器的构造方式更加神秘。

如果“动态加载”失败,负责创建 Selector 的类是 sun.nio.ch.DefaultSelectorProvider,我没有它的源代码,所以我可以跟踪 IOException 的来源。

Java 的关于选择器的 javadoc 根本没有帮助,它们只是声明:

抛出:IOException - 如果发生 I/O 错误

如果有人对 Selector.open() 创建的这个集市 IOException 有任何见解,请告诉我。另外回答一个更实际的问题,应该“正确”处理 IOException(例如消息框、闪光灯、工具包哔声等)还是只是隐藏在日志/空 catch 块中。

【问题讨论】:

    标签: java nio ioexception


    【解决方案1】:

    简短的回答是它特定于平台和实现,因此您几乎别无选择;你应该抓住它并处理它。而且由于这将是一个非常罕见的事件(之后你不会有Selector),这可能是一个花里胡哨的事情。选项 B 是忽略它,让它到达堆栈顶部并停止事情。

    长答案是,在 Linux 上,使用当前的默认实现,它不会抛出。如果它 >= 2.6 内核,openSelector() 将实例化并返回一个EPollSelectorImpl。如果它 PollSelectorImpl。这些类的构造函数都没有抛出IOException

    然而,在 Windows 上,您会得到一个 WindowsSelectorImpl,其构造函数确实抛出 IOException。我必须深入挖掘以找出导致它的原因,但显然有些东西可以。

    同样,这是一个实现细节,所以它在未来总是会改变。

    您可以提取 openjdk 的完整源代码以查看这些类的源代码。

    【讨论】:

    • 感谢您的信息。在任意连接随机异常时,他们确实应该给出一些理由。特定于实现与否,说当an I/O error occurs 不够好时,此方法可能会抛出 IOException。无论如何,我懒得为此拉源代码。但是,如果您确实找到任何东西,请使用此信息更新您的答案。如果其他人没有新消息,我会在一段时间后接受。
    【解决方案2】:

    它允许实现抛出 IOExceptions,原因自然不会在 API 级别指定。例如,Selector 的 Windows 实现使用内部节点为管道的选择树来处理可选通道数超过 Windows 最大值的情况。所以选择器必须能够打开管道,这可能会失败。

    【讨论】:

    • 似乎每个人都将此归咎于 Windows 实现。我知道这超出了问题范围,但是您知道任何其他可能引发此类异常的实现吗?我会适当地处理它,这是肯定的,但我很想知道如何在其他实现上设置选择器通道。
    • 我不会因为任何事情“责备 Windows 实施”。无论实现是什么,在创建选择器时都可能遇到错误,无论这在平台上意味着什么,因此它必须能够抛出异常,因此设计者选择了 IOException,这很合乎逻辑。
    猜你喜欢
    • 2016-10-03
    • 2010-11-13
    • 1970-01-01
    • 2016-11-14
    • 2012-08-08
    • 2012-12-15
    • 2014-01-10
    相关资源
    最近更新 更多