Spec-Zone.ru › OpenJDK 24

Класс SwitchPoint

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

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

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

Когда защищённый делегат создаётся из защищённой пары, пара инкапсулируется в новый обработчик методов 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)
Устанавливает все заданные точки переключения в состояние инвалидации.

Методы, объявленные в классе java.lang.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(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)

invalidateAll

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

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

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

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

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

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

© 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://download.java.net/java/early_access/jdk24/docs/api/java.base/java/lang/invoke/SwitchPoint.html

Spec-Zone.ru

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