Spec-Zone.ru › OpenJDK 8

Класс 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]));
     }
 }

Конструкторы

Конструктор и описание
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. В этом случае некоторые ненулевые элементы в массиве могут быть обработаны до того, как метод вернет исключение. Какие именно (если таковые есть) зависит от реализации.

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

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

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

© 1993, 2020, 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.

Spec-Zone.ru

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