Класс 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
- См. также:
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
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 этого селектора или не будет прерван текущий поток — в зависимости от того, что произойдет раньше.
Этот метод эквивалентен вызову двухаргументного метода 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.
https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/nio/channels/Selector.html