Writable получается всегда, когда есть свободное место в output буфере у какого-либо сокета.
Технически, метод write() всего лишь записывает данные в специальный буфер в памяти, привязанный к сетевому сокету. Размер этого буфера регулируется опцией
SO_SNDBUF. Это in-memory операция. Реальная работа с сетью на этом этапе не происходит.
Данные из буфера в сеть отправляются уже непосредственно операционной системой. Скорость опустошения буфера зависит от разных факторов, в частности, пропускной способности сети и производительности машины на другом конце провода. Если в буфере есть хотя бы один свободный байт, то флаг OP_WRITE будет установлен.
На OP_WRITE нужно подписываться только когда есть данные, которые можно отправить удаленной стороне и отписываться сразу, как только вся порция данных будет записана в сокет. В противном случае, в результате каждого вызова Selector.select() вы будете получать список всех сокетов, у которых есть свободное место в буфере. А так как данных для записи у вас нет - только впустую потратите ресурс процессора.
Образно говоря, на OP_READ вы подписываетесь, когда хотите послушать что говорят другие, а на OP_WRITE, когда вам самим есть что сказать.