我试图通过使用Selector:
为SocketChannel添加写超时public int write(ByteBuffer buf, long timeout, SocketChannel socketChannel, Selector selector) {
int written = socketChannel.write(buf);
if (written == 0) {
SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_WRITE);
try {
selector.select(timeout);
if (Thread.interrupted()) {
throw new InterruptedIOException();
}
written = socketChannel.write(buf);
} finally {
selectionKey.cancel();
}
}
return written;
}
计划是重复使用选择器并在每次超时后取消注册。但显然我得到了相同的selectionKey,如果我调用我的方法两次并且根本无法写入,则之前取消了。在第二次方法调用期间调用register时,这会导致CancelledKeyException。在第一次被取消之后,我想我会得到一个新的selectionKey。
那我该怎么做?我想在寄存器之前或取消之后调用selectNow(),为了清除已取消的键会解决它但是看起来很奇怪,有更好的方法吗?