В този урок ще се запознаем с класа Selector . Този клас е в пакета java.nio.channels , така че не е необходимо да изтегляте or конфигурирате нищо, за да го използвате. Обектът Selector може да наблюдава един or повече обекти Channel , да проверява готовността им за четене/запис и т.н. И най-важното, селекторът се нуждае от един поток, а не от един поток на канал.

Ние създаваме селектори, използвайки статичния отворен метод:

Selector selector = Selector.open();

След това каналите могат да бъдат регистрирани в обект за избор:

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

Вторият параметър на регистърния метод определя коя операция ще наблюдава селектора. Ако трябва да наблюдавате няколко операции наведнъж, можете да използвате побитово ИЛИ:

SelectionKey.OP_READ | SelectionKey.OP_WRITE

Когато възникне I/O действие на някой от каналите, селекторът ни уведомява. По този начин можете например да четете данни от голям брой източници на данни.

Тук трябва да споменем, че каналът трябва да е в неблокиращ режим, за да може да се използва със селектор:

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

От това следва, че селекторът няма да работи с FileChannel , тъй като FileChannel не може да бъде превключен в неблокиращ режим ( методът configureBlocking е деклариран в класа SelectableChannel , който FileChannel не наследява).

От диаграмата можете да видите, че селекторите са подходящи за използване с гнезда. Ще работим с тях в края на втория модул.

SelectionKey

Когато регистрираме канал със селектор, получаваме aSelectionKeyобект. Този обект съдържа данни за регистрация на канал.

Можете да използвате ключа, за да определите дали каналът е готов за определена стойност:

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

Ключът може да ви даде съответния канал и селектор:

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

Можете да прикрепите всеки обект към ключ, за да го проследявате в бъдеще. Това може да се направи or по време на регистрация на канал (чрез третия аргумент), or по-късно:

  1. SelectionKey ключ = channel.register(селектор, SelectionKey.OP_ACCEPT, обект);

  2. key.attach(обект);

По-късно можете да получите прикачения обект от ключа:

Object object = key.attachment();

Заключение

След като регистрираме канали със селектор, ние можем:

  • разберете броя на каналите, готови за извършване на определени операции
  • блокирайте изпълнението на нашата програма, докато не бъде готов поне един канал
  • вземете комплект ключове за готови канали
  • и още

В края на втория модул ще изпробваме селектори на практика.