在使用 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;
看起来该类是在运行时动态加载的,这让这些选择器的构造方式更加神秘。
如果“动态加载”失败,负责创建选择器的类是 sun.nio.ch.DefaultSelectorProvider
,我没有它的源代码,所以我能做到的就这些在追踪 IOException 的来源方面。
Java 关于选择器的 javadoc 根本没有帮助,它们只是声明:
Throws: IOException - If an I/O error occurs
如果有人对这个由 Selector.open() 创建的集市 IOException 有任何见解,请告诉我。另外回答一个更实际的问题,IOException 是否应该被“正确”处理(例如消息框、闪光灯、工具包蜂鸣声等)或只是隐藏在日志/空捕获 block 中。
最佳答案
简短的回答是它是特定于平台和实现的,因此您几乎别无选择;你应该捕获它并处理它。由于这将是一个非常罕见的事件(之后您将不会有 Selector
),因此它可能是花里胡哨的事情。选项 B 忽略它,让它到达堆栈顶部并停止运行。
长答案是,在 Linux 上,使用当前的默认实现,它不会抛出。如果它是 >= 2.6 内核,openSelector()
将实例化并返回一个 EPollSelectorImpl
。如果它是 < 2.6,你会得到一个 PollSelectorImpl
。这些类的构造函数都不会抛出 IOException
。
但是,在 Windows 上,您会得到一个 WindowsSelectorImpl
,其构造函数会抛出 IOException
。我必须更深入地研究以找出导致它的原因,但显然有些事情可以。
同样,这是一个实现细节,所以它在未来总是可以改变的。
您可以提取 openjdk 的完整源代码以查看这些类的源代码。
关于Java NIO 选择器.open() IOException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21055636/