Spec-Zone .ru
спецификации, руководства, описания, API
|
public class SwitchPoint extends Object
A SwitchPoint
объект, который может опубликовать изменения состояния к другим потокам. Точка переключения находится первоначально в допустимом состоянии, но может в любое время быть изменена на недопустимое состояние. Аннулирование не может быть инвертировано. Точка переключения может объединить защищенную пару дескрипторов метода в защищенный delegator. Защищенный delegator является дескриптором метода, который делегирует к одному из старых дескрипторов метода. Состояние точки переключения определяет, какой из этих двух получает делегацию.
Единственная точка переключения может использоваться, чтобы управлять любым числом дескрипторов метода. (Косвенно, поэтому, это может управлять любым числом сайтов вызова.) Это делается при использовании единственной точки переключения как фабрика для того, чтобы объединить любое число защищенных пар дескриптора метода в защищенный delegators.
Когда защищенный delegator создается из защищенной пары, пара обертывается в новый дескриптор метода M
, который постоянно связывается с точкой переключения, которая создала это. Каждая пара состоит из цели T
и нейтрализация F
. В то время как точка переключения допустима, вызовы к M
делегируются к T
. После того, как это лишается законной силы, вызовы делегируются к F
.
Аннулирование является глобальной переменной и непосредственный, как будто точка переключения, содержавшая энергозависимая логическая переменная, с которой консультируются относительно каждого звонка 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)
Наборы все данные точки переключения в недопустимое состояние.
|
public boolean hasBeenInvalidated()
Обсуждение: Из-за односторонней природы аннулирования, когда-то точка переключения начинает возвращать true для hasBeenInvalidated
, это будет всегда делать так в будущем. С другой стороны допустимая точка переключения, видимая к другим потокам, может быть лишена законной силы в любой момент, из-за запроса другим потоком.
Так как аннулирование является глобальной и непосредственной работой, выполнение этого запроса, на допустимой точке переключения, должно быть внутренне упорядочено с любыми другими потоками, которые могли вызвать аннулирование. Этот запрос может поэтому быть дорогим. Рекомендуемый способ создать оцененный булевской переменной дескриптор метода, который запрашивает состояние аннулирования точки переключения s
должен вызвать s.guardWithTest
на constant
истинные и ложные дескрипторы метода.
public MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback)
Цель и нейтрализация должны иметь точно тот же самый тип метода, и получающийся объединенный дескриптор метода будет также иметь этот тип.
target
- дескриптор метода, выбранный точкой переключения, пока это допустимоfallback
- дескриптор метода, выбранный точкой переключения после того, как это лишается законной силыNullPointerException
- если любым параметром является нульIllegalArgumentException
- если два типа метода не соответствуютMethodHandles.guardWithTest(java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle, java.lang.invoke.MethodHandle)
public static void invalidateAll(SwitchPoint[] switchPoints)
Эта работа, вероятно, будет дорога и должна использоваться экономно. Если возможный, это должно быть буферизовано для пакетной обработки на наборах точек переключения.
Если switchPoints
содержит нулевой элемент, a NullPointerException
будет повышен. В этом случае некоторые ненулевые элементы в массиве могут быть обработаны прежде, чем метод возвращается неправильно. То, какие элементы они (если любой) является зависящим от реализации.
Обсуждение: По причинам производительности, invalidateAll
не виртуальный метод на единственной точке переключения, а скорее применяется к ряду точек переключения. Некоторые реализации могут подвергнуться крупному фиксированному накладному расходу на обработку одной или более операций аннулирования, но маленькой инкрементной стоимости для каждого дополнительного аннулирования. В любом случае эта работа, вероятно, будет дорогостоящей, так как другие потоки, вероятно, придется так или иначе прервать, чтобы заставить их заметить обновленное состояние точки переключения. Однако, можно заметить, что единственный вызов, чтобы лишить законной силы несколько точек переключения имеет тот же самый формальный эффект так много вызовов, каждый на только одной из точек переключения.
Примечание реализации: Простые реализации SwitchPoint
может использовать частное MutableCallSite
опубликовать состояние точки переключения. В такой реализации, invalidateAll
метод может просто изменить цель сайта вызова, и издать один приказ, чтобы синхронизировать все частные сайты вызова.
switchPoints
- массив сайтов вызова, которые будут синхронизироватьсяNullPointerException
- если switchPoints
ссылка массива является нулем, или массив содержит нуль
Для дальнейшей ссылки API и документации разработчика, см.
Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.