NIO Selector: Como registrar corretamente o novo canal ao selecionar

Eu tenho uma subclasseThread com um privadoSelector e um públicoregister(SelectableChannel channel, ...) método que permite que outros segmentos registrem canais para o seletor.

Como respondidoAqui, o canalregister() blocos durante o seletorselect() / select(long timeout) então precisamoswakeup() o seletor.

Meu thread seleciona indefinidamente (a menos que seja interrompido) e ele realmente consegue entrar no próximo select antes do canalregister() é chamado. Então eu pensei em usar um cadeado simplessynchronized blocos para garantir aregister() acontece primeiro.

O código: (código irrelevante removido para legibilidade)

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 bloqueio simples permiteregister() acontecer antes que o segmento continue com o próximo loop de seleção. Tanto quanto eu testei, isso funciona como suposto.

Questões: É uma maneira "boa" de fazê-lo ou há alguma desvantagem séria nisso? Seria melhor usar uma lista ou fila (como sugeridoAqui) para armazenar canais para registro, ou um bloqueio mais sofisticado comoisto em vez de? Quais seriam os prós / contras disso? Ou existem maneiras "ainda melhores"?

questionAnswers(3)

yourAnswerToTheQuestion