取消选择键,但之后重复使用

时间:2015-06-11 10:55:07

标签: java select nio

我想首先将一个频道注册到选择器,仅在连接时执行select(),然后在只写时执行。{/ p>

类似的东西:

SelectionKey key = server.register(selector, SelectionKey.OP_CONNECT);
server.connect(address);
int readyChannels = 0;
while (readyChannels == 0) readyChannels = selector.select(config.connectTimeout);
server.finishConnect();
key.cancel();

key = server.register(selector, SelectionKey.OP_WRITE);
// write something to the channel and check timeout 
// with selector.select(config.writeTimeout)

但是,当我到达代码中的第二个register(...)时,我会得到CancelledKeyException

还有其他方法吗?

这样做的正确方法是每次都定义一个新选择器吗?

P.S。我知道我可以使用key.isWritable()等。

1 个答案:

答案 0 :(得分:1)

  1. 如果finishConnect()返回false,则表示无法正确处理,就好像它已返回true一样。

  2. 你的问题是你没有在取消和注册之间调用选择器,所以有未完成的业务。这里最简单的解决方案是删除取消和寄存器,直接调整现有选择键的interestOps。

  3. 然而,由于您只是在连接完成之前才有效阻塞,因此在阻塞模式下进行连接会更简单,之后会进入非阻塞状态,对于后续的I / ○:

    // Still in blocking mode, no register() yet ...
    server.socket().connect(address, connectTimeout);
    server.configureBlocking(false);
    key = server.register(selector, SelectionKey.OP_WRITE);
    

    ...注意如果超时到期,则抛出异常。

  4. 我很少遇到一个案例,其中在客户端实际上在非阻塞模式下使用NIO是有意义的。