Java 在选择器中检测ServerSocketChannel何时关闭。选择()

Java 在选择器中检测ServerSocketChannel何时关闭。选择(),java,nio,socketchannel,Java,Nio,Socketchannel,当我将selector.select()注册到SocketChannel,并在单独的线程中关闭SocketChannel的对等线程时,selector.select()返回,并设置该通道的读取操作。如果向选择器注册了ServerSocketChannel,并且关闭了ServerSocketChannel,则selector.select()不会返回。在selector.select()中被阻止时,是否仍可以检测到ServerSocketChannel已关闭 我尝试使用selector.wakeu

当我将selector.select()注册到SocketChannel,并在单独的线程中关闭SocketChannel的对等线程时,selector.select()返回,并设置该通道的读取操作。如果向选择器注册了ServerSocketChannel,并且关闭了ServerSocketChannel,则selector.select()不会返回。在selector.select()中被阻止时,是否仍可以检测到ServerSocketChannel已关闭

我尝试使用selector.wakeup(),并检查了一组键(不是选定的键),查看该集中是否有任何未打开的通道,但一旦在ServerSocketChannel上完成关闭,它就会从selector注销,因此它不在select.keys()集中

我是否可以检测到服务器socketchannel 在选择器中被阻止时被关闭。选择()

如果您想要
selector.select()
返回,以便您可以在选定的键中提取闭合通道,然后按文档中的说明选择否

它仅在至少选择一个通道后返回,此 调用选择器的唤醒方法,或调用当前线程 中断,以先到者为准

由于没有像
op_CLOSE
这样的兴趣op,因此在频道关闭时使
select
方法返回的唯一方法是显式地唤醒
。但密钥被隐式取消

不管怎么说,封闭式渠道也没什么用


另外,
EPollSelectorProvider
正在代理对底层
epoll
的调用,并且它也没有您想要的事件

为什么??关门了。你不需要再做什么了。你对此无能为力。您需要对自己的数据结构执行的任何操作都可以在关闭时执行。@user207421,当所有通道都关闭时,我希望线程退出。如果唯一打开的通道是ServerSocketChannel,并且它被关闭,我希望有一种方法可以退出select(),我会看到没有通道注册到选择器,线程将退出。因此,当注册的通道数降至零时退出。注意,您关于关闭注册的
SocketChannel
时会发生什么的说法是不正确的。实际发生的情况是,该密钥被取消,就像对
服务器socketchannel
一样,因此它被排除在所选密钥集中,实际上它已从注册的密钥集中删除。因此,其
SelectionKey
无法读取。即使您单独保存它,它也会抛出
CancelledKeyException
为什么要使用它。您所描述的发生在对等方关闭连接时。@user207421,您是正确的。我的意思是当对等机关闭时,而不是SocketChannel关闭。这就更清楚了为什么当我关闭ServerSocketChannel时,select不会返回。我将编辑我的问题以澄清问题。关闭
服务器socketchannel
后,您必须唤醒
选择器,否则注册和对象指针将保留,无法进行垃圾收集。它将在唤醒后自动从
选择器中删除,因为手动关闭
服务器socketchannel
时会取消
选择键。