Класс селектор
- Все реализованные интерфейсы:
-
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.
- Since:
- 1.4
- See Also:
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
protected |
Инициализирует новый экземпляр данного класса. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
abstract void |
close() |
Закрывает этот селектор. |
abstract boolean |
isOpen() |
Определяет, открыт ли этот селектор. |
abstract Set |
keys() |
Возвращает набор ключей этого селектора. |
static Selector |
open() |
Открывает селектор. |
abstract SelectorProvider |
provider() |
Возвращает поставщика, который создал этот канал. |
abstract int |
select() |
Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода. |
abstract int |
select |
Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода. |
int |
select |
Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода. |
int |
select |
Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода. |
abstract Set |
selectedKeys() |
Возвращает набор выбранных ключей селектора. |
abstract int |
selectNow() |
Выбирает набор ключей, соответствующие каналы которых готовы к операциям ввода-вывода. |
int |
selectNow |
Выбирает и выполняет действие над ключами, соответствующие каналы которых готовы к операциям ввода-вывода. |
abstract Selector |
wakeup() |
Принудительно заставляет первую операцию выбора, которая ещё не возвратила результат, вернуть результат немедленно. |
Подробное описание конструкторов
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 этого селектора вызван, текущий поток прерван или истекает заданный период ожидания, в зависимости от того, что произойдёт раньше.
Указанный метод действия accept вызывается с ключом для каждого канала, который готов выполнить операцию, идентифицированную набором интересов ключа. Метод accept может вызываться более одного раза для одного и того же ключа, но с набором операций готовности, содержащим подмножество операций, для которых канал готов (как описано выше). Метод accept вызывается, будучи синхронизированным на селекторе и его наборе выбранных ключей. Следует проявлять особую осторожность, чтобы избежать тупика с другими потоками, которые также синхронизированы с этими объектами. Операции выбора не являются рекурсивными, и поэтому действие должно позаботиться о том, чтобы не пытаться выполнить операцию выбора на том же селекторе. Поведение при попытке рекурсивной операции выбора зависит от реализации и поэтому не определено. Если действие закрывает селектор, то ClosedSelectorException возникает при завершении действия. Действие не запрещено закрывать каналы, зарегистрированные с селектором, или отменять ключи или изменять набор интересов ключа. Если канал выбран, но его ключ отменён или его набор интересов изменён до того, как действие выполнено по ключу, то поведение, вызывается ли действие (может вызываться с ключом invalid), зависит от реализации. Исключение, возникшее в действии, передаётся вызывающей стороне.
Этот метод не гарантирует реального времени: он планирует таймаут так, как если бы вызывал метод Object.wait(long).
- Требования к реализации:
- По умолчанию реализация удаляет все ключи из набора выбранных ключей, вызывает
select(long)с заданным таймаутом, а затем выполняет действие для каждого ключа, добавленного в набор выбранных ключей. По умолчанию реализация не обнаруживает действие, выполняющее рекурсивную операцию выбора. Набор выбранных ключей может или не быть пустым по завершении стандартной реализации. - Параметры:
-
action- Действие, которое нужно выполнить -
timeout- Если положительно, блокируется доtimeoutмиллисекунд, больше или меньше, в ожидании, пока канал станет готовым; если ноль, блокируется неопределённо; не должно быть отрицательным - Возвращает:
- Количество уникальных ключей, обработанных, возможно ноль
- Исключения:
-
IOException- Если произошла ошибка ввода-вывода -
ClosedSelectorException- Если этот селектор закрыт или закрыт действием -
IllegalArgumentException- Если значение аргумента таймаута отрицательно - С тех пор как:
- 11
select
public int select(Consumer<SelectionKey> action) throws IOException
Этот метод выполняет блокирующую операцию выбора. Он просыпается от запроса к операционной системе только когда по крайней мере один канал выбран, метод wakeup этого селектора вызван или текущий поток прерван, в зависимости от того, что произойдёт раньше.
Этот метод эквивалентен вызову метода 2-аргументного select с таймаутом 0 для неопределённого блокирования.
- Требования к реализации:
- Стандартная реализация вызывает метод 2-аргументный <
select> с таймаутом0. - Параметры:
-
action- Действие, которое нужно выполнить - Возвращает:
- Количество уникальных ключей, обработанных, возможно ноль
- Исключения:
-
IOException- Если произошла ошибка ввода-вывода -
ClosedSelectorException- Если этот селектор закрыт или закрыт действием - С тех пор как:
- 11
selectNow
public int selectNow(Consumer<SelectionKey> action) throws IOException
Этот метод выполняет неблокирующую операцию выбора.
Вызов этого метода очищает действие любых предыдущих вызовов метода wakeup.
- Требования к реализации:
- Реализация по умолчанию удаляет все ключи из набора выбранных ключей, вызывает
selectNow(), а затем выполняет действие для каждого ключа, добавленного в набор выбранных ключей. Реализация по умолчанию не обнаруживает выполнение действия с повторным выбором. Набор выбранных ключей может быть пустым или не пустым по завершении реализации по умолчанию. - Параметры:
-
action- действие, которое нужно выполнить - Возвращает:
- Количество уникальных потребленных ключей, возможно ноль
- Исключения:
-
IOException- если произошла ошибка ввода-вывода -
ClosedSelectorException- если этот селектор закрыт или закрыт действием - С:
- 11
wakeup
public abstract Selector wakeup()
Если другой поток в настоящее время заблокирован в операции выбора, то этот вызов вернет немедленно. Если операция выбора в настоящее время не выполняется, то следующий вызов операции выбора вернет немедленно, если selectNow() или selectNow(Consumer) не вызваны тем временем. В любом случае возвращаемое значение этим вызовом может быть ненулевым. Последующие операции выбора будут блокироваться как обычно, если этот метод не вызывается тем временем.
Вызов этого метода более одного раза между двумя последовательными операциями выбора имеет тот же эффект, что и вызов его только один раз.
- Возвращает:
- Этот селектор
close
public abstract void close() throws IOException
Если поток в настоящее время заблокирован в одном из методов выбора этого селектора, он прерывается так, как если бы вызывался метод wakeup селектора.
Любые неотмененные ключи, все еще связанные с этим селектором, становятся недопустимыми, их каналы дерегистрируются, а любые другие ресурсы, связанные с этим селектором, освобождаются.
Если этот селектор уже закрыт, вызов этого метода не оказывает никакого влияния.
После закрытия селектора любая дальнейшая попытка использовать его, кроме как путем вызова этого метода или метода wakeup, приведет к выбрасыванию исключения ClosedSelectorException.
- Определено в:
-
closeв интерфейсеAutoCloseable - Определено в:
-
closeв интерфейсеCloseable - Исключения:
-
IOException- если произошла ошибка ввода-вывода
© 1993, 2023, 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/21/docs/api/java.base/java/nio/channels/Selector.html