は、Java 8で比較的最近published article about replacing executors by actorsはそうのような匿名の内部クラスRunnable
を使用して次のように述べている。ランナブル対メソッド参照とガベージ
// Functional operation
executor.execute(new Runnable() {
System.out.println(data);
});
は、理想的には同じことを実行するより多くのガベージコレクタに優しい技術に置き換えることができます操作:
Actor<String> actor = new Actor<>(parentExecutor, ::onMessage);
// Equivalent functional operation
actor.act("Hello world");
public void onMessage(String message) {
System.out.println(message);
}
それはone should generally use method references over anonymous inner classes(すなわちnew Runnable
、new Callable
)という意味があります。そのアイデアはしばらくありました。ここでは、このActorパターンを使用すると、より効率的ですが、記事で明示的に説明されていない別の微妙さがあるようです。
executor.execute(() -> System.out.println(data));
は明らかに非効率的だろう(少し、いえ)コンパイラが持っているので、生成されたメソッドinvokedynamic
「コール・サイト」を作成し、呼び出されたときにそれを参照するために:
は、私が使用していることを理解しています。
は、(1)直接メソッド参照がinvokedynamic
メソッド生成のオーバーヘッドを持っていないと(2)ができることをここでの利点です加えて、あなたは、この直接参照するメソッドのパラメータを渡すことができますか?記事で紹介したこのアイデアを、すでに使用していて知っているパターンよりも重要なものにしているのは何ですか?
最初にリンクされた記事は間違っています。各メソッド参照のオブジェクトを作成しなければならないので、GCに優しいわけではありません。これは、匿名クラスオブジェクトを異なるタイプのオブジェクトに置き換えたばかりです。メソッド参照またはラムダは新しいクラスを作成せず、それは2番目のリンクのポイントですが、改善されたGCの最初のリンクのポイントは間違っているため、クラスが残っていない方が良いです。あなたがウェブ上で見つけたものすべてを信じてはいけません。 – Andreas
@アンドレアスあなたが言っていることが真実ならば、私は驚いています。それ以上のGCの親切ではないこと。私は、Clebert Suconic - 記事の著者であり、新しいActiveMQに関するApacheの一次コミッター - おそらくそのことを述べる前に宿題をしていたというメリットについて語っています。 – Dovmo
@Andreas匿名クラスは囲むオブジェクトをキャプチャし、ラムダまたはメソッドリファレンスは必要なものだけをキャプチャします。たぶんそれはもっとGCに優しいという意味ですか? – maaartinus