Spec-Zone.ru › OpenJDK 25

Класс SwitchPoint

java.lang.Object
java.lang.invoke.SwitchPoint
public class SwitchPoint extends Object

SwitchPoint — это объект, который может публиковать переходы состояния для других потоков. Точка переключения изначально находится в действительном состоянии, но в любой момент может быть переведена в недействительное состояние. Отмена действия недействительного состояния невозможна. Точка переключения может объединить защищённую пару дескрипторов методов в защищённый делегатор. Защищённый делегатор — это дескриптор метода, который делегирует вызов одному из исходных дескрипторов методов. Состояние точки переключения определяет, которому из двух будет делегирован вызов.

Одна точка переключения может использоваться для управления любым количеством дескрипторов методов. (Косвенно, следовательно, она может управлять любым количеством точек вызова.) Для этого одна точка переключения используется как фабрика, объединяющая любое количество пар защищённых дескрипторов методов в защищённые делегаторы.

При создании защищённого делегатора из защищённой пары эта пара оборачивается в новый дескриптор метода M, который постоянно связан с создавшей его точкой переключения. Каждая пара состоит из целевого T и резервного F. Пока точка переключения действительна, вызовы M делегируются T. После того как она становится недействительной, вызовы делегируются F.

Действие распространяется глобально и происходит немедленно, как если бы точка переключения содержала volatile-переменную boolean, значение которой проверялось при каждом вызове M. Это действие также необратимо: точка переключения может изменить состояние только один раз. После перехода в недействительное состояние точка переключения всегда будет делегировать вызов F. После этого guardWithTest может игнорировать T и возвращать F.

Пример использования точки переключения:

MethodHandle MH_strcat = MethodHandles.lookup()
    .findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class));
SwitchPoint spt = new SwitchPoint();
assert(!spt.hasBeenInvalidated());
// the following steps may be repeated to re-use the same switch point:
MethodHandle worker1 = MH_strcat;
MethodHandle worker2 = MethodHandles.permuteArguments(MH_strcat, MH_strcat.type(), 1, 0);
MethodHandle worker = spt.guardWithTest(worker1, worker2);
assertEquals("method", (String) worker.invokeExact("met", "hod"));
SwitchPoint.invalidateAll(new SwitchPoint[]{ spt });
assert(spt.hasBeenInvalidated());
assertEquals("hodmet", (String) worker.invokeExact("met", "hod"));

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

Примечание по реализации: Точка переключения ведёт себя так, как если бы она была реализована поверх MutableCallSite, примерно следующим образом:

public class SwitchPoint {
    private static final MethodHandle
        K_true  = MethodHandles.constant(boolean.class, true),
        K_false = MethodHandles.constant(boolean.class, false);
    private final MutableCallSite mcs;
    private final MethodHandle mcsInvoker;
    public SwitchPoint() {
        this.mcs = new MutableCallSite(K_true);
        this.mcsInvoker = mcs.dynamicInvoker();
    }
    public MethodHandle guardWithTest(
            MethodHandle target, MethodHandle fallback) {
        // Note:  mcsInvoker is of type ()boolean.
        // Target and fallback may take any arguments, but must have the same type.
        return MethodHandles.guardWithTest(this.mcsInvoker, target, fallback);
    }
    public static void invalidateAll(SwitchPoint[] spts) {
        List<MutableCallSite> mcss = new ArrayList<>();
        for (SwitchPoint spt : spts)  mcss.add(spt.mcs);
        for (MutableCallSite mcs : mcss)  mcs.setTarget(K_false);
        MutableCallSite.syncAll(mcss.toArray(new MutableCallSite[0]));
    }
}
С момента выпуска:
1.7

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

Конструктор Описание
SwitchPoint()
Создаёт новую точку переключения.

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

Модификатор и тип Метод Описание
MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback)
Возвращает дескриптор метода, который всегда делегирует вызов целевому или резервному дескриптору.
boolean hasBeenInvalidated()
Определяет, была ли эта точка переключения переведена в недействительное состояние.
static void invalidateAll(SwitchPoint[] switchPoints)
Переводит все указанные точки переключения в недействительное состояние.

Методы, объявленные в классе Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Подробное описание конструкторов

SwitchPoint

public SwitchPoint()
Создаёт новую точку переключения.

Подробное описание методов

hasBeenInvalidated

public boolean hasBeenInvalidated()
Определяет, была ли эта точка переключения переведена в недействительное состояние.

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

Поскольку инвалидация — глобальная операция, выполняемая немедленно, выполнение этого запроса для действительной точки переключения должно быть внутренне упорядочено относительно выполнения любых других потоков, которые могут вызвать инвалидацию. Поэтому этот запрос может быть затратным. Рекомендуемый способ создания дескриптора метода с логическим значением, который запрашивает состояние инвалидации точки переключения s, — вызвать s.guardWithTest для дескрипторов методов constant, возвращающих true и false.

Возвращает:
true, если эта точка переключения переведена в недействительное состояние

guardWithTest

public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback)
Возвращает дескриптор метода, который всегда делегирует вызов целевому или резервному дескриптору. Дескриптор метода будет делегировать вызов целевому дескриптору, пока точка переключения действительна. После этого он будет постоянно делегировать вызов резервному дескриптору.

Целевой и резервный дескрипторы должны иметь в точности одинаковый тип метода; полученный объединённый дескриптор метода также будет иметь этот тип.

Параметры:
target — дескриптор метода, выбираемый точкой переключения, пока она действительна
fallback — дескриптор метода, выбираемый точкой переключения после перехода в недействительное состояние
Возвращает:
объединённый дескриптор метода, который всегда вызывает целевой или резервный дескриптор
Вызывает исключение:
NullPointerException — если один из аргументов равен null
IllegalArgumentException — если типы двух методов не совпадают
См. также:
  • MethodHandles.guardWithTest(MethodHandle, MethodHandle, MethodHandle)

invalidateAll

public static void invalidateAll(SwitchPoint[] switchPoints)
Переводит все указанные точки переключения в недействительное состояние. После выполнения этого вызова ни один поток не будет считать какую-либо из этих точек переключения действительной.

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

Если switchPoints содержит элемент null, будет сгенерировано исключение NullPointerException. В этом случае некоторые ненулевые элементы массива могут быть обработаны до того, как метод завершится с ошибкой. Какие именно элементы (если таковые имеются) будут обработаны, зависит от реализации.

Обсуждение: По соображениям производительности invalidateAll — не виртуальный метод для одной точки переключения, а операция, применяемая к набору точек переключения. Некоторые реализации могут иметь значительные постоянные издержки при выполнении одной или нескольких операций инвалидации, но небольшие дополнительные издержки для каждой последующей инвалидации. В любом случае эта операция, вероятно, будет затратной, поскольку для того, чтобы другие потоки заметили обновлённое состояние точки переключения, их может потребоваться каким-либо образом прервать. Однако один вызов для инвалидации нескольких точек переключения имеет тот же формальный эффект, что и множество вызовов, каждый из которых применяется только к одной точке переключения.

Примечание по реализации: Простые реализации SwitchPoint могут использовать частный MutableCallSite для публикации состояния точки переключения. В такой реализации метод invalidateAll может просто изменить целевой объект точки вызова, а затем вызвать синхронизацию всех частных точек вызова один раз.

Параметры:
switchPoints — массив точек вызова, которые требуется синхронизировать
Вызывает исключение:
NullPointerException — если ссылка на массив switchPoints равна null или массив содержит null

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

© 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/lang/invoke/SwitchPoint.html

Spec-Zone.ru

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