gpt4 book ai didi

Java NIO select() 返回时没有选择键 - 为什么?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:04:39 25 4
gpt4 key购买 nike

在编写一些测试代码时,我发现 Selector.select() 可以在没有 Selector.selectedKeys() 包含任何要处理的键的情况下返回。当我用

注册一个 accept()ed channel 时,这是在一个紧密的循环中发生的
SelectionKey.OP_READ | SelectionKey.OP_CONNECT

作为感兴趣的操作。

根据文档,select() 应该在以下情况下返回:

1) 有可以采取行动的 channel 。

2) 您显式调用 Selector.wakeup() - 未选择任何键。

3) 您显式地使用 Thread.interrupt() 执行 select() 的线程 - 没有选择键。

如果我在 select() 之后没有得到键,我一定是在情况 (2) 和 (3) 中。但是,我的代码没有调用 wakeup() 或 interrupt() 来启动这些返回。

关于导致此行为的原因有什么想法吗?

最佳答案

简短回答:从您对已接受连接感兴趣的操作列表中删除 OP_CONNECT - 已连接已接受连接。

我设法重现了这个问题,这可能正是您遇到的情况:

import java.net.*;
import java.nio.channels.*;


public class MyNioServer {
public static void main(String[] params) throws Exception {
final ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(true);
serverChannel.socket().bind(new InetSocketAddress("localhost", 12345));
System.out.println("Listening for incoming connections");
final SocketChannel clientChannel = serverChannel.accept();
System.out.println("Accepted connection: " + clientChannel);


final Selector selector = Selector.open();
clientChannel.configureBlocking(false);
final SelectionKey clientKey = clientChannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_CONNECT);
System.out.println("Selecting...");
System.out.println(selector.select());
System.out.println(selector.selectedKeys().size());
System.out.println(clientKey.readyOps());
}
}

上述服务器收到连接后,连接上的第一个 select() 无阻塞退出,并且没有准备好操作的键。我不知道为什么 Java 会以这种方式运行,但似乎很多人都被这种行为所困扰。

在 Windows XP 上的 Sun JVM 1.5.0_06 以及 Linux 2.6 上的 Sun JVM 1.5.0_05 和 1.4.2_04 上的结果是相同的。

关于Java NIO select() 返回时没有选择键 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/204186/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com