Nesta lição, conheceremos a classe Selector . Esta classe está no pacote java.nio.channels , então você não precisa baixar ou configurar nada para usá-la. Um objeto Selector pode monitorar um ou mais objetos Channel , verificar sua prontidão para leitura/gravação, etc. E o mais importante, um seletor precisa de um fluxo, não um fluxo por canal.

Criamos seletores usando o método open estático :

Selector selector = Selector.open();

Depois disso, os canais podem ser registrados em um objeto seletor:

SelectionKey key1 = channel1.register(selector, SelectionKey.OP_READ);
SelectionKey key2 = channel2.register(selector, SelectionKey.OP_WRITE);

O segundo parâmetro do método register determina qual operação o seletor irá monitorar. Se você precisa monitorar várias operações ao mesmo tempo, pode usar OR bit a bit:

SelectionKey.OP_READ | SelectionKey.OP_WRITE

Quando ocorre uma ação de I/O em qualquer um dos canais, o seletor nos notifica. Dessa forma, você pode, por exemplo, ler dados de um grande número de fontes de dados.

Aqui precisamos mencionar que um canal deve estar no modo sem bloqueio para que seja usado com um seletor:

channel1.configureBlocking(false);
channel2.configureBlocking(false);
SelectionKey key1 = channel1.register(selector, SelectionKey.OP_READ);
SelectionKey key2 = channel2.register(selector, SelectionKey.OP_WRITE);

Segue-se que um seletor não funcionará com um FileChannel , porque um FileChannel não pode ser alternado para o modo sem bloqueio (o método configureBlocking é declarado na classe SelectableChannel , que FileChannel não herda).

No diagrama, você pode ver que os seletores são adequados para uso com soquetes. Trabalharemos com eles no final do segundo módulo.

SelectionKey

Ao registrar um canal com um seletor, obtemos umSelectionKeyobjeto. Este objeto contém dados sobre o registro do canal.

Você pode usar a tecla para determinar se o canal está pronto para um determinado valor:

key.isReadable()
key.isAcceptable()
key.isConnectable()
key.isWritable()

A tecla pode fornecer o canal e o seletor correspondentes:

Channel channel = key.channel();
Selector selector = key.selector();

Você pode anexar qualquer objeto a uma chave para rastreá-lo no futuro. Isso pode ser feito durante o registro do canal (através do terceiro argumento) ou posteriormente:

  1. Chave SelectionKey = channel.register(seletor, SelectionKey.OP_ACCEPT, objeto);

  2. chave.attach(objeto);

Mais tarde, você pode obter o objeto anexado da chave:

Object object = key.attachment();

Conclusão

Depois de registrar os canais com um seletor, podemos:

  • descubra o número de canais prontos para executar operações especificadas
  • bloquear a execução do nosso programa até que pelo menos um canal esteja pronto
  • obter um conjunto de chaves para canais prontos
  • e mais

Ao final do segundo módulo, experimentaremos os seletores na prática.