В този урок ще се запознаем с класа 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 по-късно:
-
SelectionKey ключ = channel.register(селектор, SelectionKey.OP_ACCEPT, обект);
-
key.attach(обект);
По-късно можете да получите прикачения обект от ключа:
Object object = key.attachment();
Заключение
След като регистрираме канали със селектор, ние можем:
- разберете броя на каналите, готови за извършване на определени операции
- блокирайте изпълнението на нашата програма, докато не бъде готов поне един канал
- вземете комплект ключове за готови канали
- и още
В края на втория модул ще изпробваме селектори на практика.
GO TO FULL VERSION