SwitchPoint — 상태 전환을 다른 스레드에 공개하는 객체

SwitchPoint — 상태 전환을 다른 스레드에 공개하는 객체

SwitchPoint상태 전환(state transition)을 다른 스레드에 공개(publish) 할 수 있는 객체예요. 스위치 포인트는 처음에 유효(valid) 상태지만, 언제든 무효(invalid) 상태로 바뀔 수 있고, 무효화는 되돌릴 수 없어요.

출처: Java API Reference

본문

스위치 포인트는 보호된(guarded) 메서드 핸들 쌍guarded delegator로 결합해요. guarded delegator는 두 옛 메서드 핸들 중 하나에 위임하는 메서드 핸들인데, 스위치 포인트의 상태가 어느 쪽에 위임할지를 결정해요.

하나의 스위치 포인트로 임의 개수의 메서드 핸들을 제어할 수 있어요 (따라서 간접적으로 임의 개수의 콜 사이트도 제어할 수 있어요). 이는 하나의 스위치 포인트를 팩토리로 삼아, 임의 개수의 guarded 쌍을 guarded delegator로 결합해서 이뤄져요.

guarded delegator가 guarded 쌍으로부터 만들어질 때, 그 쌍은 새 메서드 핸들 M에 감싸여 그 M은 이 스위치 포인트에 영구적으로 연결돼요. 각 쌍은 타깃 T와 폴백(fallback) F로 구성돼요. 스위치 포인트가 유효한 동안 M에 대한 호출은 T에 위임되고, 무효화된 후엔 F에 위임돼요.

무효화는 전역적이고 즉각적이에요 — 마치 스위치 포인트가 M을 호출할 때마다 참조되는 volatile boolean 변수를 담고 있는 것처럼요. 무효화는 영구적이라, 스위치 포인트는 상태를 한 번만 바꿀 수 있어요. 무효화된 후에는 항상 F에 위임돼요.

다음은 스위치 포인트 동작 예시예요.

MethodHandle MH_strcat = MethodHandles.lookup()
    .findVirtual(String.class, "concat", MethodType.methodType(String.class, String.class));
SwitchPoint spt = new SwitchPoint();
assert(!spt.hasBeenInvalidated());
// 다음 단계들은 같은 스위치 포인트를 재사용하기 위해 반복 가능:
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"));

스위치 포인트는 하위 클래스 없이도 유용하며, 하위 클래스화할 수도 있어요.

static 메서드

  • static void invalidateAll(SwitchPoint[] switchPoints) — 주어진 모든 스위치 포인트를 무효화해요. 스위치 포인트는 되돌릴 수 없으므로, 이미 무효화된 포인트는 그대로 두고 아직 유효한 포인트만 무효화돼요.

인스턴스 메서드

  • boolean hasBeenInvalidated() — 이 스위치 포인트가 무효화된 적이 있는지 여부를 반환해요.
  • MethodHandle guardWithTest(MethodHandle target, MethodHandle fallback) — 이 스위치 포인트가 유효한 동안 target에, 무효화된 후엔 fallback에 위임하는 메서드 핸들을 반환해요. 두 핸들은 같은 타입이어야 해요.

더 알아보기 (Learn more)