In questa lezione, faremo conoscenza con la classe Selector . Questa classe si trova nel pacchetto java.nio.channels , quindi non è necessario scaricare o configurare nulla per utilizzarla. Un oggetto Selector può monitorare uno o più oggetti Channel , verificare la loro disponibilità alla lettura/scrittura, ecc. E, soprattutto, un selettore necessita di un flusso, non di un flusso per canale.

Creiamo selettori utilizzando il metodo statico aperto :

Selector selector = Selector.open();

Successivamente, i canali possono essere registrati in un oggetto selettore:

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

Il secondo parametro del metodo register determina quale operazione verrà monitorata dal selettore. Se devi monitorare più operazioni contemporaneamente, puoi utilizzare l'OR bit a bit:

SelectionKey.OP_READ | SelectionKey.OP_WRITE

Quando si verifica un'azione di I/O su uno qualsiasi dei canali, il selettore ci avvisa. In questo modo è possibile, ad esempio, leggere i dati da un gran numero di origini dati.

Qui dobbiamo menzionare che un canale deve essere in modalità non bloccante per poter essere utilizzato con un selettore:

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

Ne consegue che un selettore non funzionerà con un FileChannel , perché un FileChannel non può essere commutato in modalità non bloccante (il metodo configureBlocking è dichiarato nella classe SelectableChannel , che FileChannel non eredita).

Dallo schema si vede che i selettori sono adatti all'uso con le prese. Lavoreremo con loro alla fine del secondo modulo.

SelectionKey

Quando registriamo un canale con un selettore, otteniamo aSelectionKeyoggetto. Questo oggetto contiene dati sulla registrazione del canale.

È possibile utilizzare la chiave per determinare se il canale è pronto per un determinato valore:

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

La chiave può darti il ​​canale e il selettore corrispondenti:

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

Puoi allegare qualsiasi oggetto a una chiave per rintracciarlo in futuro. Questo può essere fatto durante la registrazione del canale (tramite il terzo argomento) o successivamente:

  1. Chiave SelectionKey = channel.register(selettore, SelectionKey.OP_ACCEPT, oggetto);

  2. key.attach(oggetto);

Successivamente, puoi ottenere l'oggetto allegato dalla chiave:

Object object = key.attachment();

Conclusione

Dopo aver registrato i canali con un selettore, possiamo:

  • scoprire il numero di canali pronti per eseguire operazioni specificate
  • bloccare l'esecuzione del nostro programma finché almeno un canale non è pronto
  • ottenere un set di chiavi per i canali pronti
  • e altro ancora

Alla fine del secondo modulo, proveremo in pratica i selettori.