2

this 参照が構築中にエスケープする問題 (Brian Goetz やその他の Java Concurrency in Practice で呼び出されている) は、シングルスレッド プログラムまたはマルチスレッド プログラムだけに影響しますか? つまり、クラスがとにかくスレッドセーフであると想定されていない場合、構築中に this 参照をエスケープさせても大丈夫ですか?

編集:たとえば、ここで:

public class ThisEscape {
    public ThisEscape(EventSource source) {
        source.registerListener(
            new EventListener() {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
    }
}

EDIT2:私の質問の動機は、プラグインWindowBuilder for EclipseがJFrameのコンストラクターでアクションリスナーを作成(または作成するように見える...)し、デフォルトで匿名クラスをそれらに渡すことで、 this 参照をエスケープできるようにすることです...

4

3 に答える 3

4

一般的に言えば、オブジェクトが完全に構築されるまで、オブジェクトを使用しようとすべきではありません。完全に初期化される前にオブジェクトを他のコードに渡すと、非常に注意しない限り、結果が混乱する可能性があります。シングルスレッドプログラムでも。

そうは言っても、オブジェクトが後で使用されることがわかっている場合は特に問題にならないことがあります。

于 2013-06-01T22:00:01.867 に答える
3

「this」参照のエスケープを許可しても、必ずしも問題が発生するわけではありません。問題なく動作する可能性がありますが、他のコードがそれをどう処理するかに完全に依存しています。

では、コンストラクターでこれをリークしないことがベスト プラクティスである理由は何ですか? EventSource が「接続中」イベントを登録関数内からすぐに送信するとどうなるでしょうか。何が起こるのですか?doSomething() が呼び出されます (注意してください、あなたはまだコンストラクターの途中であり、オブジェクトの初期化が完了していない可能性があります)。メソッドの動作に完全に依存しますが、次のいずれかが当てはまります。

  1. doSomething で必要なものはすべて、リスナーが登録される前に初期化され、うまくいきます。
  2. 何かが null であり、それを無視すると、予期しない結果が生じる
  3. null であってはならない (NPE など) ときに何かが null になった結果、何かが爆発します。

しかし、あなたは、それはそのイベントを送信しないと言います。大丈夫ですよね?まあ、他の誰かがそれを変更し、そのようなものを送信し始めるまでは、コードを直接変更することなく自発的に壊れます.

短い形式: できればそれを避けてください。それは頭痛を引き起こす可能性があります。何らかの理由で絶対に必要な場合は、リークする前にできる限りすべてを初期化するように注意し、何が起こるかを理解するために細心の注意を払い、将来のトラブルの可能性があることを認識してください.

于 2013-06-01T22:14:42.350 に答える