Tengo un Thread
subclasificado con un Selector
privado y un método register(SelectableChannel channel, ...)
público que permite que otros subprocesos registren canales en el selector.Selector de NIO: cómo registrar correctamente el nuevo canal al seleccionar
como respondida here, register()
bloques del canal durante el selector de select()
/select(long timeout)
por lo que necesitamos wakeup()
el selector.
Mi hilo selecciona indefinidamente (a menos que se interrumpa) y realmente logra entrar en la siguiente selección antes de llamar al register()
del canal. Así que pensé usar un bloqueo simple con bloques synchronized
para asegurar que el register()
ocurra primero.
el código: (código irrelevante eliminado para facilitar la lectura)
public class SelectorThread extends Thread {
...
public void register(SelectableChannel channel, Attachment attachment) throws IOException {
channel.configureBlocking(false);
synchronized (this) { // LOCKING OCCURS HERE
selector.wakeup();
channel.register(selector,
SelectionKey.OP_READ,
attachment);
}
}
@Override
public void run() {
int ready;
Set<SelectionKey> readyKeys;
while (!isInterrupted()) {
synchronized (this) {} // LOCKING OCCURS HERE
try {
ready = selector.select(5000);
} catch (IOException e) {
e.printStackTrace();
continue;
}
if (ready == 0) {
continue;
}
readyKeys = selector.selectedKeys();
for (SelectionKey key : readyKeys) {
readyKeys.remove(key);
if (!key.isValid()) {
continue;
}
if (key.isReadable()) {
...
}
}
}
}
}
Este simple bloqueo permite register()
ocurra antes de que el hilo continúa con el siguiente bucle de selección. Por lo que he probado, esto funciona como se supone.
Preguntas: ¿Es esa una "buena" manera de hacerlo o hay serias desventajas en eso? ¿Sería mejor usar una Lista o Cola (como se sugiere here) para almacenar los canales para el registro, o un bloqueo más sofisticado como this en su lugar? ¿Cuáles serían los Pros/Contras de eso? ¿O hay formas "aún mejores"?
Posible duplicación de [bloques de subprocesos de Java mientras se registra el canal con selector mientras se llama a select(). ¿Qué hacer?] (Https://stackoverflow.com/questions/1057224/java-thread-blocks-while-registering-channel-with-selector-while-select-is-cal) – Flow