Существует улов, который мне стоит нескольких часов, чтобы выяснить. Рассмотрим следующий код:
SocketChannel socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 22));
socket.configureBlocking(false);
Selector selector = Selector.open();
SelectionKey selkey = socket.register(selector, 0);
....
selkey.interestOps(SelectionKey.OP_READ);
selector.select(1000);
System.out.println("Selecting r, return " +
(selector.selectedKeys().contains(selkey) && selkey.isReadable() ? "r" : "") +
(selector.selectedKeys().contains(selkey) && selkey.isWritable() ? "w" : ""));
Он печатает «Выбор r, возврат w». Таким образом, iswritable() может быть истинным, пока интересуется только OP_READ. Это происходит, если OP_WRITE включен в предыдущий вызов select(), а текущий select() возвращает 0, что означает, что selkey не обновляется.
Полный код доказательства находится здесь: https://gist.github.com/wuyongzheng/43cc9dc07e13124663d1. Для запуска вам нужен SSH-сервер в порту 22.
Это другой вопрос, но при каких обстоятельствах (кроме соединения, которое закрывается между isWriteable() и write()), может ли ошибка записи/получить задержку? – tstenner
вот что говорит SelectionKey javadoc. – irreputable