Java Selector NIO读取问题

标签 java selector nio

相关代码 -- 注意 Instructions 只是一个类,其中包含多个将对数据进行操作的方法。创建一个新线程对读取的数据进行操作。

阅读主题:

while(true) {
     System.out.println(".");
     if(selector.select(500) == 0)
          continue;

     System.out.println("processing read");

     for(SelectionKey sk : selector.keys()) {
          Instructions ins = myHashTable.get(sk);
          if(ins == null) { 
               myHashTable.put(sk, new Instructions(sk));
               ins = myHashTable.get(sk);
          }
          ins.readChannel();
     }
}

阅读 channel

public void readChannel() {
     BufferedReader reader = new BufferedReader(Channels.newReader((ReadableByteChannel) this.myKey.channel(), "UTF-8"));
     Worker w = new Worker(this, reader.readLine());
     (new Thread(w)).start();
}

然后新线程调用更多的Instructions 方法。

当 ins 函数完成时,它可能写入一个 Writer:

Writer out = Channels.newWriter((WritableByteChannel) key.channel(), "UTF-8");
out.write(output);
out.flush();

我可以确认我的客户端(一个 flash 电影),然后接收并处理输出。

最后,w 退出。

从客户端接收到第一条消息并成功处理后,READ THREAD 循环不再处理更多消息。我相信 key 已在选择器中注册并准备好读取。我已经通过循环所有键来检查它们是否可以通过 channel 上的 isReadable & isRegistered 读取,并且结果在所有情况下都是正确的。但是,当从客户端发送第二条消息时,我在读取线程中看到的唯一响应是“.”。字符不是每半秒打印一次,而是持续更快。那么,我相信数据在 channel 中,但由于某种原因,选择器没有选择任何键。

谁能帮帮我?

最佳答案

我认为您在这里遗漏了几点。

  • 首先,您应该在 for 循环中使用 selector.selectedKeys()
    正如 Vijay 所提到的。
  • 应该从 selectedKeys 中删除 key 处理 key 后。否则 key 不会 自动删除,因此选择器甚至可能会连续旋转 如果有一个键设置了感兴趣的操作位。 (这可能是 你的问题)。
  • 最后,我们应该对 channel 如果 channel 已准备就绪。即,仅当 isReadable() 返回 true 并尝试仅在 isWritable() 为 真的。不要忘记验证 key 。

关于Java Selector NIO读取问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1477306/

相关文章:

java - 如何打印文件中以条件字符串开头和结尾的某些行

java - 线程的上下文类加载器和普通类加载器的区别

java - 使用gson在java中写入json文件

java - 为我的 zip 创建文件系统时未找到提供程序异常?

java - 多个 NIO react 器,还是只有一个?

java - 字节缓冲区性能

java - 使用 Maven 依赖插件创建带有依赖 jar 的库 jar

java - 为什么 select() 在我的程序中消耗这么多 CPU 时间?

testing - TestCafe:具有动态 ID 的 Web 应用程序(XAF 应用程序)

ios - 如何获取类方法的选择器?