モジュール java.base
パッケージ java.lang.invoke

クラスMutableCallSite

java.lang.Object
java.lang.invoke.CallSite
java.lang.invoke.MutableCallSite
直系の既知のサブクラス:
AbstractRelinkableCallSite

public non-sealed class MutableCallSite extends CallSite
MutableCallSiteは、ターゲット変数の動作が通常のフィールドと同じであるようなCallSiteです。 MutableCallSiteにリンクされたinvokedynamic命令は、すべての呼出しをそのサイトの現在のターゲットに委譲します。 可変コール・サイトの動的インボーカも、各呼出しをそのサイトの現在のターゲットに委譲します。

メソッド・ハンドル・チェーンに状態変数を導入する可変コール・サイトの例を、次に示します。


MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
MethodHandle MH_name = name.dynamicInvoker();
MethodType MT_str1 = MethodType.methodType(String.class);
MethodHandle MH_upcase = MethodHandles.lookup()
    .findVirtual(String.class, "toUpperCase", MT_str1);
MethodHandle worker1 = MethodHandles.filterReturnValue(MH_name, MH_upcase);
name.setTarget(MethodHandles.constant(String.class, "Rocky"));
assertEquals("ROCKY", (String) worker1.invokeExact());
name.setTarget(MethodHandles.constant(String.class, "Fred"));
assertEquals("FRED", (String) worker1.invokeExact());
// (mutation can be continued indefinitely)
 

同じコール・サイトをいくつかの場所で一度に使用できます。


MethodType MT_str2 = MethodType.methodType(String.class, String.class);
MethodHandle MH_cat = lookup().findVirtual(String.class,
  "concat", methodType(String.class, String.class));
MethodHandle MH_dear = MethodHandles.insertArguments(MH_cat, 1, ", dear?");
MethodHandle worker2 = MethodHandles.filterReturnValue(MH_name, MH_dear);
assertEquals("Fred, dear?", (String) worker2.invokeExact());
name.setTarget(MethodHandles.constant(String.class, "Wilma"));
assertEquals("WILMA", (String) worker1.invokeExact());
assertEquals("Wilma, dear?", (String) worker2.invokeExact());
 

ターゲット値の非同期: 可変コール・サイトのターゲットに書き込んでも、ほかのスレッドがその更新された値を認識するようにはなりません。 更新されたコール・サイトに関する適切な同期アクションを実行しないスレッドは、古いターゲット値をキャッシュに入れ、新しいターゲット値の使用を無期限に遅らせる可能性があります。 (これは、オブジェクト・フィールドに適用されるJavaメモリー・モデルの通常の結果です。)

syncAll操作は、ほかの同期が存在していなくてもスレッドが新しいターゲット値を受け入れるように強制するための手段を提供します。

更新頻度の高いターゲット値では、代わりに揮発性コール・サイトの使用を検討してください。

導入されたバージョン:
1.7