在使用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错误
如果有人对由IOException ()创建的集市Selector.open有任何见解,请告诉我。另外,回答一个更实际的问题,是IOException被“正确地”处理(例如,消息箱、闪光灯、工具包的哔哔声等等),还是只是藏在一个日志/空捕捉块中。
发布于 2014-01-11 00:48:51
简单地说,它是特定于平台和实现的,因此您几乎没有选择;您应该抓住它并处理它。由于这将是一个非常罕见的事件(在此之后你将没有Selector),这可能是一件简单的事情。选项B是忽略它,让它到达堆栈的顶部并停止操作。
长期的答案是,在Linux上,对于当前的默认实现,它不会抛出。如果它是>= 2.6内核,openSelector()将实例化并返回一个EPollSelectorImpl。如果是< 2.6,就会得到一个PollSelectorImpl。这两个类的构造函数都不会抛出IOException。
然而,在Windows上,您会得到一个WindowsSelectorImpl,其构造函数确实会抛出IOException。我得更深入地找出是什么原因造成的,但很明显,有些东西可以。
不过,这还是一个实现细节,所以将来总是会改变的。
您可以为openjdk提取完整的源代码来查看这些类的源代码。
发布于 2014-01-13 00:53:56
它允许实现抛出IOExceptions,其原因自然不是在API级别指定的。例如,Selector的Windows实现使用一个选择树,其内部节点是管道,用于处理可选择通道数超过Windows最大值的情况。因此,选择器必须能够打开管道,这可能会失败。
https://stackoverflow.com/questions/21055636
复制相似问题