In deze les maken we kennis met de klasse Selector . Deze klasse zit in het pakket java.nio.channels , dus u hoeft niets te downloaden of te configureren om het te gebruiken. Een Selector- object kan een of meer Channel- objecten bewaken, hun lees-/schrijfgereedheid controleren, enz. En het allerbelangrijkste: een selector heeft één stream nodig, niet één stream per kanaal.

We maken selectors met behulp van de statische open methode:

Selector selector = Selector.open();

Daarna kunnen kanalen worden geregistreerd in een selectorobject:

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

De tweede parameter van de registermethode bepaalt welke bewerking de selector zal controleren. Als u meerdere bewerkingen tegelijk moet bewaken, kunt u bitsgewijze OR gebruiken:

SelectionKey.OP_READ | SelectionKey.OP_WRITE

Wanneer een I/O-actie plaatsvindt op een van de kanalen, meldt de selector ons. Zo kun je bijvoorbeeld data uit een groot aantal databronnen lezen.

Hier moeten we vermelden dat een kanaal in niet-blokkerende modus moet staan ​​om het met een selector te kunnen gebruiken:

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

Hieruit volgt dat een selector niet werkt met een FileChannel , omdat een FileChannel niet kan worden omgeschakeld naar de niet-blokkerende modus (de methode configureBlocking wordt gedeclareerd in de klasse SelectableChannel , die FileChannel niet erft).

Uit het diagram kunt u zien dat keuzeschakelaars geschikt zijn voor gebruik met stopcontacten. Aan het einde van de tweede module gaan we met ze aan de slag.

Selectiesleutel

Bij het registreren van een kanaal met een selector krijgen we eenSelectiesleutelvoorwerp. Dit object bevat gegevens over kanaalregistratie.

Met de toets kun je bepalen of het kanaal klaar is voor een bepaalde waarde:

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

De sleutel kan u het corresponderende kanaal en de selector geven:

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

U kunt elk object aan een sleutel koppelen om het in de toekomst te volgen. Dit kan worden gedaan tijdens de kanaalregistratie (via het derde argument) of later:

  1. SelectionKey-toets = channel.register(selector, SelectionKey.OP_ACCEPT, object);

  2. toets.attach(object);

Later kunt u het bijgevoegde object uit de sleutel halen:

Object object = key.attachment();

Conclusie

Na het registreren van kanalen met een selector, kunnen we:

  • ontdek het aantal kanalen dat klaar is om bepaalde bewerkingen uit te voeren
  • blokkeer de uitvoering van ons programma totdat ten minste één kanaal gereed is
  • krijg een set sleutels voor kant-en-klare kanalen
  • en meer

Aan het einde van de tweede module gaan we selectors in de praktijk uitproberen.