Spec-Zone.ru › OpenJDK 25

Класс 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 набора. Нельзя непосредственно добавлять ключи в набор выбранных ключей.

Выбор

Операция выбора запрашивает у базовой операционной системы сведения об обновлении готовности каждого зарегистрированного канала к выполнению любой из операций, указанных в наборе интересующих операций его ключа. Существует два вида операций выбора:

  1. Методы select(), select(long) и selectNow() добавляют в набор выбранных ключей ключи каналов, готовых к выполнению операции, или обновляют набор готовых операций ключей, уже находящихся в наборе выбранных ключей.

  2. Методы select(Consumer), select(Consumer, long) и selectNow(Consumer) выполняют действие над ключом каждого канала, готового к выполнению операции. Эти методы не добавляют ключи в набор выбранных ключей.

Операции выбора, добавляющие ключи в набор выбранных ключей

Во время каждой операции выбора ключи могут добавляться в набор выбранных ключей селектора и удаляться из него, а также удаляться из его наборов ключей и отмененных ключей. Выбор выполняется методами select(), select(long) и selectNow() и состоит из трех шагов:

  1. Каждый ключ из набора отмененных ключей удаляется из каждого набора ключей, в котором он содержится, а его канал удаляется из регистрации. После этого шага набор отмененных ключей становится пустым.

  2. У базовой операционной системы запрашиваются сведения об обновлении готовности каждого оставшегося канала к выполнению любой из операций, указанных в наборе интересующих операций его ключа на момент начала операции выбора. Для канала, готового хотя бы к одной такой операции, выполняется одно из следующих действий:

    1. Если ключ канала еще не находится в наборе выбранных ключей, он добавляется в этот набор, а набор готовых операций изменяется так, чтобы в нем были указаны ровно те операции, к которым канал, согласно текущим данным, готов. Любые сведения о готовности, ранее сохраненные в наборе готовых операций, отбрасываются.

    2. В противном случае ключ канала уже находится в наборе выбранных ключей, поэтому набор его готовых операций изменяется так, чтобы в нем были указаны новые операции, к которым, согласно данным, канал готов. Любые сведения о готовности, ранее сохраненные в наборе готовых операций, сохраняются; другими словами, набор готовности, возвращенный базовой системой, побитово объединяется с текущим набором готовых операций ключа.

    Если у всех ключей, находившихся в наборе ключей в начале этого шага, пустые наборы интересующих операций, то ни набор выбранных ключей, ни наборы готовых операций ключей не обновляются.
  3. Если во время выполнения шага (2) в набор отмененных ключей были добавлены какие-либо ключи, они обрабатываются, как описано в шаге (1).

Единственное принципиальное различие между тремя методами выбора заключается в том, блокируется ли операция выбора в ожидании готовности одного или нескольких каналов и, если блокируется, на какое время.

Операции выбора, выполняющие действие над выбранными ключами

Во время каждой операции выбора ключи могут удаляться из наборов ключей, выбранных ключей и отмененных ключей селектора. Выбор выполняется методами select(Consumer), select(Consumer,long) и selectNow(Consumer) и состоит из трех шагов:

  1. Каждый ключ из набора отмененных ключей удаляется из каждого набора ключей, в котором он содержится, а его канал удаляется из регистрации. После этого шага набор отмененных ключей становится пустым.

  2. У базовой операционной системы запрашиваются сведения об обновлении готовности каждого оставшегося канала к выполнению любой из операций, указанных в наборе интересующих операций его ключа на момент начала операции выбора.

    Для канала, готового хотя бы к одной такой операции, набор готовых операций ключа канала устанавливается таким образом, чтобы в нем были указаны ровно те операции, к которым готов канал, после чего вызывается метод select, чтобы обработать ключ канала. Любые сведения о готовности, ранее сохраненные в наборе готовых операций, отбрасываются перед вызовом действия.

    Если канал готов более чем к одной операции, действие может быть вызвано несколько раз, при этом ключ канала и набор готовых операций изменяются так, чтобы включать подмножество операций, к которым готов канал. Если действие вызывается для одного и того же ключа несколько раз, его набор готовых операций никогда не содержит биты операций, которые были в наборе при предыдущих вызовах действия в рамках одной операции выбора.

  3. Если во время выполнения шага (2) в набор отмененных ключей были добавлены какие-либо ключи, они обрабатываются, как описано в шаге (1).

Параллельное выполнение

Селектор и его набор ключей можно безопасно использовать из нескольких параллельно работающих потоков. Однако его набор выбранных ключей и набор отмененных ключей небезопасны для такого использования.

Операции выбора синхронизируются сначала на самом селекторе, затем на наборе выбранных ключей. Кроме того, во время описанных выше шагов (1) и (3) они синхронизируются на наборе отмененных ключей.

Изменения наборов интересующих операций ключей селектора, выполненные во время операции выбора, не влияют на эту операцию; они будут учтены при следующей операции выбора.

Ключи можно отменить, а каналы закрыть в любой момент. Поэтому наличие ключа в одном или нескольких наборах ключей селектора не означает, что ключ действителен или его канал открыт. Если существует вероятность того, что другой поток отменит ключ или закроет канал, прикладной код должен при необходимости тщательно синхронизировать доступ и проверять эти условия.

Поток, заблокированный во время операции выбора, может быть прерван другим потоком одним из трех способов:

  • вызовом метода wakeup селектора;

  • вызовом метода close селектора; или

  • вызовом метода interrupt заблокированного потока; в этом случае устанавливается его статус прерывания и вызывается метод wakeup селектора.

Метод close синхронизируется на селекторе и его наборе выбранных ключей в том же порядке, что и операция выбора.

Набор ключей селектора можно безопасно использовать из нескольких параллельно работающих потоков. Операции получения данных из набора ключей обычно не блокируются, поэтому могут выполняться одновременно с новыми регистрациями, добавляющими элементы в набор, или с этапами отмены операций выбора, удаляющими ключи из набора. Итераторы и сплитераторы возвращают элементы, отражающие состояние набора в какой-либо момент начиная с момента создания итератора или сплитератора. Они не вызывают исключение ConcurrentModificationException.

Как правило, набор выбранных ключей селектора небезопасен для использования из нескольких параллельно работающих потоков. Если такой поток может напрямую изменять набор, доступ к нему следует контролировать, синхронизируясь на самом наборе. Итераторы, возвращаемые методами iterator набора, являются быстро завершающимися: если набор изменен после создания итератора любым способом, кроме вызова собственного метода remove итератора, будет выброшено исключение ConcurrentModificationException.

Начиная с версии:
1.4
См. также:
  • SelectableChannel
  • SelectionKey

Краткое описание конструкторов

Selector()
Модификатор Конструктор Описание
protected
Инициализирует новый экземпляр этого класса.

Краткое описание методов

Модификатор и тип Метод Описание
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()
Заставляет первую еще не завершившуюся операцию выбора немедленно завершиться.

Методы, объявленные в классе 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 этого селектора, не будет прерван текущий поток или не истечет заданный период ожидания — в зависимости от того, что произойдет раньше.

Для каждого канала, готового выполнить операцию, указанную в наборе интересующих операций его ключа, вызывается метод 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 — если произошла ошибка ввода-вывода

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в разделе Документация Java SE, содержащем более подробные описания для разработчиков, обзоры основных понятий, определения терминов, обходные решения и рабочие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или ее аффилированных лиц в США и других странах.
Авторское право © 1993, 2025, Oracle и/или ее аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065, США.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API