Spec-Zone.ru › OpenJDK 21

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

Поскольку инвалидация является глобальной и мгновенной операцией, выполнение этого запроса на валидной точке переключения должно быть внутренне последовательно связано с любыми другими потоками, которые могли бы вызвать инвалидацию. Поэтому этот запрос может быть дорогим. Рекомендуемый способ построения обработчика метода типа boolean, который запрашивает состояние инвалидации точки переключения s, состоит в вызове s.guardWithTest для обработчиков методов 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, 2023, 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/21/docs/api/java.base/java/lang/invoke/SwitchPoint.html

Spec-Zone.ru

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