public class SwitchPoint extends Object
一个SwitchPoint
是可以发布状态转换到其他线程对象。交换点最初处于有效状态,但在任何时候都可以更改为无效状态。无效不能被逆转。开关点可以结合一个守卫对方法处理成一个守护者。守护者是一种方法处理,代表一种旧的方法处理。切换点的状态决定了两个获取委托的哪一个。
一个单一的开关点可以用来控制任何数量的方法处理。(间接的,因此,它可以控制任意数量的调用站点。)这是采用单开关点作为组合任意数量的保护方法处理对防御危险的工厂完成。
当一个守护者是从保护对创造,对包裹在一种新的方法处理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])); } }
Constructor and Description |
---|
SwitchPoint()
创建一个新的开关点。
|
Modifier and Type | Method and Description |
---|---|
MethodHandle |
guardWithTest(MethodHandle target, MethodHandle fallback)
返回一个方法处理的总代表或者目标或回退。
|
boolean |
hasBeenInvalidated()
确定这个开关点已经失效呢。
|
static void |
invalidateAll(SwitchPoint[] switchPoints)
将给定的开关点设置为无效状态。
|
public boolean hasBeenInvalidated()
讨论:由于无效的单向性,一旦一个开关点开始回归真实的hasBeenInvalidated
,它会一直这样做的未来。另一方面,一个有效的开关点对其他线程可见可能失效,在任何时候,由于被另一个线程的请求。
由于失效是一个全球性的即时操作,该查询的执行,在一个有效的开关点,必须内部测序与任何其他线程可能导致失效。因此,这个查询可能是昂贵的。推荐的方式建立一个布尔值的方法处理查询一个开关点s
失效状态是呼吁constant
真假的方法处理s.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)
public static void invalidateAll(SwitchPoint[] switchPoints)
此操作可能是昂贵的,应谨慎使用。如果可能的话,它应该被缓冲到一组开关点上的批量处理。
如果switchPoints
包含一个null元素,一NullPointerException
将提高。在这种情况下,数组中的一些非空元素可能在方法返回异常之前处理过。这些元素(如果有的话)是依赖于实现的。
讨论:由于性能原因,invalidateAll
不是在一个单一的开关点的虚方法,而是采用一组开关点。一些实现可能会产生一个大的固定开销成本处理一个或多个无效操作,但一个小的增量成本为每个额外的失效。在任何情况下,这种操作可能是昂贵的,因为其他线程可能必须以某种方式被中断,以使他们注意到更新的开关点状态。然而,可以发现,几个开关失效点一次调用具有相同的形式影响许多电话,每只一个开关点。
注:SwitchPoint
实现的简单的实现可能使用私有MutableCallSite
发布一个开关点的状态。在这样一个实现的方法可以简单的改变,invalidateAll
调用网站的目标,并发出一个呼叫synchronize所有私人电话网站。
switchPoints
-调用站点同步阵列
NullPointerException
-如果
switchPoints
数组引用为空或数组包含一个空
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.