Класс Selector
- java.lang.Object
-
- java.nio.channels.Selector
- Все реализуемые интерфейсы:
-
Closeable,AutoCloseable
- Прямые известные подклассы:
AbstractSelector
public abstract class Selector extends Object implements Closeable
Мультиплексор объектов SelectableChannel.
Селектор можно создать, вызвав метод open этого класса, который будет использовать системный по умолчанию selector provider для создания нового селектора. Селектор также можно создать, вызвав метод openSelector пользовательского поставщика селекторов. Селектор остается открытым до тех пор, пока он не будет закрыт с помощью метода close.
Регистрация канала, подлежащего выбору, с селектором представлена объектом SelectionKey. Селектор поддерживает три набора ключей выбора:
Набор ключей содержит ключи, представляющие текущие регистрации каналов этого селектора. Этот набор возвращается методом
keys.Набор выбранных ключей — это набор ключей, для каждого из которых канал был обнаружен готовым к выполнению хотя бы одной из операций, указанных в наборе интересов ключа во время предыдущей операции выбора, добавляющей ключи или обновляющей ключи в наборе. Этот набор возвращается методом
selectedKeys. Набор выбранных ключей всегда является подмножеством набора ключей.Набор отмененных ключей — это набор ключей, которые были отменены, но каналы которых ещё не были дерегистрированы. К этому набору нет прямого доступа. Набор отменённых ключей всегда является подмножеством набора ключей.
Все три набора пусты в вновь созданном селекторе.
Ключ добавляется в набор ключей селектора в качестве побочного эффекта регистрации канала через метод register канала. Отменённые ключи удаляются из набора ключей во время операций выбора. Сам набор ключей не может быть изменён напрямую.
Ключ добавляется в набор отменённых ключей селектора, когда он отменяется, независимо от того, закрыт ли его канал или вызван ли метод cancel. Отмена ключа приведёт к дерегистрации его канала во время следующей операции выбора, в этот момент ключ будет удалён из всех наборов ключей селектора.
Ключи добавляются в набор выбранных ключей операциями выбора. Ключ может быть удалён непосредственно из набора выбранных ключей путём вызова метода remove набора или вызова метода remove итератора iterator, полученного из набора. Все ключи могут быть удалены из набора выбранных ключей путём вызова метода clear набора. Ключи не могут быть добавлены непосредственно в набор выбранных ключей.
Выбор
Операция выбора запрашивает у основной операционной системы обновление о готовности каждого зарегистрированного канала к выполнению любой из операций, определённых набором интересов его ключа. Существуют две формы операций выбора:
Методы
select(),select(long)иselectNow()добавляют ключи каналов, готовых к выполнению операции, в набор выбранных ключей или обновляют набор готовых операций для ключей, уже присутствующих в наборе выбранных ключей.Методы
select(Consumer),select(Consumer, long)иselectNow(Consumer)выполняют действие над ключом каждого канала, готового к выполнению операции. Эти методы не добавляют ключи в набор выбранных ключей.
Операции выбора, добавляющие в набор выбранных ключей
Во время каждой операции выбора ключи могут быть добавлены и удалены из набора выбранных ключей селектора, и могут быть удалены из набора ключей и набора отменённых ключей. Выбор выполняется методами select(), select(long) и selectNow() и включает три шага:
Каждый ключ в наборе отменённых ключей удаляется из каждого набора ключей, членом которого он является, и его канал дерегистрируется. Этот шаг оставляет набор отменённых ключей пустым.
-
Основная операционная система запрашивает обновление о готовности каждого оставшегося канала к выполнению любой из операций, указанных в наборе интересов его ключа на момент начала операции выбора. Для канала, готового хотя бы к одной такой операции, выполняется одно из следующих двух действий:
Если ключ канала ещё не присутствует в наборе выбранных ключей, то он добавляется в этот набор, и его набор готовых операций изменяется таким образом, чтобы указывать точно те операции, для которых канал теперь готов. Любая информация о готовности, ранее записанная в наборе, отбрасывается.
В противном случае ключ канала уже присутствует в наборе выбранных ключей, поэтому его набор готовых операций изменяется для указания любых новых операций, для которых канал готов. Любая информация о готовности, ранее записанная в наборе, сохраняется; другими словами, набор готовности, возвращаемый основной системой, объединяется поразрядно с текущим набором готовности ключа.
Если в ходе шага (2) были добавлены ключи в набор отменённых ключей, то они обрабатываются как в шаге (1).
Единственное существенное различие между тремя методами выбора заключается в том, блокируется ли операция выбора для ожидания готовности одного или нескольких каналов, и если да, то на какой срок.
Операции выбора, выполняющие действие над выбранными ключами
Во время каждой операции выбора ключи могут быть удалены из набора ключей, набора выбранных ключей и набора отменённых ключей селектора. Выбор выполняется методами select(Consumer), select(Consumer,long) и selectNow(Consumer) и включает три шага:
Каждый ключ в наборе отменённых ключей удаляется из каждого набора ключей, членом которого он является, и его канал дерегистрируется. Этот шаг оставляет набор отменённых ключей пустым.
-
Основная операционная система запрашивает обновление о готовности каждого оставшегося канала к выполнению любой из операций, указанных в наборе интересов его ключа на момент начала операции выбора.
Для канала, готового хотя бы к одной такой операции, набор готовых операций ключа канала устанавливается таким образом, чтобы указывать точно те операции, для которых канал готов, и вызывается действие, указанное методу
select, для потребления ключа канала. Любая информация о готовности, ранее записанная в наборе, отбрасывается перед вызовом действия.Если канал готов к выполнению более чем одной операции, действие может быть вызвано более одного раза с ключом канала и набором готовых операций, изменённым на подмножество операций, для которых канал готов. Если действие вызывается более одного раза для одного и того же ключа, то его набор готовых операций никогда не содержит биты операций, которые содержались в наборе в предыдущие вызовы действия в той же операции выбора.
Если в ходе шага (2) были добавлены ключи в набор отменённых ключей, то они обрабатываются как в шаге (1).
Конкурентность
Селектор и его набор ключей безопасны для использования несколькими потоками. Его набор выбранных ключей и набор отменённых ключей, однако, не являются безопасными.
Операции выбора синхронизируются по самому селектору, затем по набору выбранных ключей. Они также синхронизируются по набору отменённых ключей во время шагов (1) и (3), описанных выше.
Изменения, внесенные в наборы интересов ключей селектора во время выполнения операции выбора, не оказывают на неё никакого влияния; они будут видны следующей операцией выбора.
Ключи могут быть отменены, и каналы могут быть закрыты в любое время. Поэтому наличие ключа в одном или нескольких наборах ключей селектора не означает, что ключ действителен или что его канал открыт. Приложения должны быть внимательны к синхронизации и проверке этих условий по мере необходимости, если существует вероятность того, что другой поток отменит ключ или закроет канал.
Поток, заблокированный в операции выбора, может быть прерван другим потоком тремя способами:
Вызвать метод
wakeupселектора,Вызвать метод
closeселектора, илиВызвать метод
interruptзаблокированного потока, в этом случае его статус прерывания будет установлен, и методwakeupселектора будет вызван.
Метод close синхронизируется по селектору и его набору выбранных ключей в том же порядке, что и операция выбора.
Набор ключей селектора безопасен для использования несколькими потоками. Операции извлечения из набора ключей обычно не блокируют, и поэтому могут перекрываться с новыми регистрациями, добавляющими в набор, или с шагами отмены операций выбора, удаляющими ключи из набора. Итераторы и разделители возвращают элементы, отражающие состояние набора в какой-то момент времени до или после создания итератора/разделителя. Они не выбрасывают ConcurrentModificationException.
Набор выбранных ключей селектора, как правило, не безопасен для использования несколькими потоками. Если такой поток может изменять набор напрямую, то доступ должен контролироваться с помощью синхронизации по самому набору. Итераторы, возвращаемые методами iterator набора, являются быстропроходящими: если набор изменяется после создания итератора каким-либо способом, кроме вызова метода remove самого итератора, то будет брошено исключение ConcurrentModificationException.
- С тех пор как:
- 1.4
- См. также:
-
SelectableChannel,SelectionKey
Конструкторы
| Модификатор | Конструктор | Описание |
|---|---|---|
protected | Selector() | Инициализирует новый экземпляр этого класса. |
Методы
| Модификатор и тип | Метод | Описание |
|---|---|---|
abstract void | close() | Закрывает этот селектор. |
abstract boolean | isOpen() | Указывает, открыт ли этот селектор. |
abstract Set<SelectionKey> | keys() | Возвращает набор ключей этого селектора. |
static Selector | open() | Открывает селектор. |
abstract SelectorProvider | provider() | Возвращает поставщика, который создал этот канал. |
abstract int | select() | Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода. |
abstract int | select(long timeout) | Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода. |
int | select(Consumer<SelectionKey> action) | Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода. |
int | select(Consumer<SelectionKey> action,
long timeout) | Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода. |
abstract Set<SelectionKey> | selectedKeys() | Возвращает набор выбранных ключей этого селектора. |
abstract int | selectNow() | Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода. |
int | selectNow(Consumer<SelectionKey> action) | Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода. |
abstract Selector | wakeup() | Заставляет первую операцию выбора, которая ещё не вернулась, вернуть результат немедленно. |
Методы, объявленные в классе java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait Подробное описание конструкторов
Selector
protected Selector()
Инициализирует новый экземпляр этого класса.
Методы
open
public static Selector open()
throws IOException Открывает селектор.
Новый селектор создается путем вызова метода openSelector системного объекта по умолчанию SelectorProvider.
- Возвращает:
- Новый селектор
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода
isOpen
public abstract boolean isOpen()
Указывает, открыт ли селектор.
- Возвращает:
-
trueесли и только если селектор открыт
provider
public abstract SelectorProvider provider()
Возвращает провайдер, который создал этот канал.
- Возвращает:
- Провайдер, который создал этот канал
keys
public abstract Set<SelectionKey> keys()
Возвращает набор ключей этого селектора.
Набор ключей не может быть изменен напрямую. Ключ удаляется только после его отмены и дерегистрации канала. Любая попытка изменить набор ключей приведет к выбросу исключения UnsupportedOperationException.
Набор является безопасным для одновременного использования несколькими потоками.
- Возвращает:
- Набор ключей этого селектора
- Выбрасывает:
-
ClosedSelectorException- если этот селектор закрыт
selectedKeys
public abstract Set<SelectionKey> selectedKeys()
Возвращает набор выбранных ключей этого селектора.
Ключи могут быть удалены, но не добавлены напрямую в набор выбранных ключей. Любая попытка добавить объект в набор ключей приведет к выбросу исключения UnsupportedOperationException.
Набор выбранных ключей не потокобезопасен.
- Возвращает:
- Набор выбранных ключей этого селектора
- Выбрасывает:
-
ClosedSelectorException- если этот селектор закрыт
selectNow
public abstract int selectNow()
throws IOException Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода.
Этот метод выполняет неблокирующую операцию выбора. Если ни один канал не стал выбираемым с момента предыдущей операции выбора, этот метод немедленно возвращает ноль.
Вызов этого метода очищает эффект любых предыдущих вызовов метода wakeup.
- Возвращает:
- Количество ключей, возможно ноль, чьи наборы операций готовности были обновлены операцией выбора
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт
select
public abstract int select(long timeout)
throws IOException Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода.
Этот метод выполняет блокирующую операцию выбора. Он возвращается только после того, как хотя бы один канал будет выбран, метод wakeup этого селектора будет вызван, текущий поток будет прерван или истечет заданный срок ожидания, что произойдет раньше.
Этот метод не гарантирует реального времени: он планирует таймаут так, как будто вызывается метод Object.wait(long).
- Параметры:
-
timeout- если положительно, ожидать доtimeoutмиллисекунд, более или менее, пока канал не станет готовым; если ноль, ожидать неопределенно; не должно быть отрицательным - Возвращает:
- Количество ключей, возможно ноль, чьи наборы операций готовности были обновлены
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт -
IllegalArgumentException- если значение аргумента таймаута отрицательно
select
public abstract int select()
throws IOException Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода.
Этот метод выполняет блокирующую операцию выбора. Он возвращается только после того, как хотя бы один канал будет выбран, метод wakeup этого селектора будет вызван или текущий поток будет прерван, что произойдет раньше.
- Возвращает:
- Количество ключей, возможно ноль, чьи наборы операций готовности были обновлены
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт
select
public int select(Consumer<SelectionKey> action,
long timeout)
throws IOException Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода.
Этот метод выполняет блокирующую операцию выбора. Он пробуждается от запроса к операционной системе только тогда, когда хотя бы один канал выбран, метод wakeup этого селектора вызван, текущий поток прерван или истекает заданный срок ожидания, что произойдет раньше.
- Implementation Requirements:
- The default implementation removes all keys from the selected-key set, invokes
select(long)with the given timeout and then performs the action for each key added to the selected-key set. The default implementation does not detect the action performing a reentrant selection operation. The selected-key set may or may not be empty on completion of the default implementation. - Parameters:
-
action- Действие, которое нужно выполнить -
timeout- Если положительно, ожидать доtimeoutмиллисекунд, более или менее, пока канал не станет готовым; если ноль, ожидать неопределенно; не должно быть отрицательным - Возвращает:
- Количество уникальных ключей, потребленных, возможно ноль
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт или закрыт действием -
IllegalArgumentException- если значение аргумента таймаута отрицательно - Since:
- 11
select
public int select(Consumer<SelectionKey> action)
throws IOException Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода.
- Implementation Requirements:
- The default implementation invokes the 2-arg
selectmethod with a timeout of0. - Parameters:
-
action- Действие, которое нужно выполнить - Возвращает:
- Количество уникальных ключей, потребленных, возможно ноль
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт или закрыт действием - Since:
- 11
selectNow
public int selectNow(Consumer<SelectionKey> action)
throws IOException Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода.
- Implementation Requirements:
- The default implementation removes all keys from the selected-key set, invokes
selectNow()and then performs the action for each key added to the selected-key set. The default implementation does not detect the action performing a reentrant selection operation. The selected-key set may or may not be empty on completion of the default implementation. - Parameters:
-
action- Действие, которое нужно выполнить - Возвращает:
- Количество уникальных ключей, потребленных, возможно ноль
- Выбрасывает:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт или закрыт действием - Since:
- 11
wakeup
public abstract Selector wakeup()
Принуждает первую операцию выбора, которая еще не вернулась, к немедленному возврату.
- Возвращает:
- Этот селектор
close
public abstract void close()
throws IOException Закрывает этот селектор.
Если поток в настоящее время заблокирован в одном из методов выбора этого селектора, то он прерывается так, как если бы был вызван метод селектора wakeup.
Любые неотмененные ключи, все еще связанные с этим селектором, аннулируются, их каналы дерегистрируются, и любые другие ресурсы, связанные с этим селектором, высвобождаются.
Если этот селектор уже закрыт, вызов этого метода не оказывает никакого эффекта.
После закрытия селектора любая последующая попытка его использования, за исключением вызова этого метода или метода wakeup, приведет к тому, что будет брошено исключение ClosedSelectorException.
- Определено в:
-
closeв интерфейсеAutoCloseable - Определено в:
-
closeв интерфейсеCloseable - Исключения:
-
IOException- Если произошла ошибка ввода-вывода
© 1993, 2020, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/nio/channels/Selector.html