Селектор
- Все реализуемые интерфейсы:
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 набора, работают по принципу fail-fast: если набор изменен после создания итератора любым способом, кроме вызова собственного метода remove итератора, будет выброшено исключение ConcurrentModificationException.
- С версии:
- 1.4
- См. также:
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
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() |
Заставляет первую еще не завершившуюся операцию выбора немедленно вернуться. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создает и возвращает копию этого объекта. |
boolean |
equals |
Показывает, «равен ли» этот объект другому объекту. |
protected void |
finalize() |
Устарело, будет удалено: этот элемент API может быть удален в будущей версии. Финализация устарела и будет удалена в одном из будущих выпусков. |
final Class |
getClass() |
Возвращает класс времени выполнения этого Object. |
int |
hashCode() |
Возвращает хеш-код этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
String |
toString() |
Возвращает строковое представление объекта. |
final void |
wait() |
Заставляет текущий поток ожидать пробуждения, обычно в результате вызова notify или interrupt. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно в результате вызова notify или interrupt, либо истечения заданного промежутка реального времени. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно в результате вызова notify или interrupt, либо истечения заданного промежутка реального времени. |
Подробное описание конструкторов
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 этого селектора или текущий поток будет прерван — в зависимости от того, что произойдет раньше.
Этот метод эквивалентен вызову метода select с двумя аргументами и тайм-аутом 0, обеспечивающим неограниченное ожидание.
- Требования к реализации:
- Реализация по умолчанию вызывает метод
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, 2025, 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.