ホームページ >Java >&#&チュートリアル >Java でオブジェクト エスケープの問題を公開して回避するにはどうすればよいですか?

Java でオブジェクト エスケープの問題を公開して回避するにはどうすればよいですか?

WBOY
WBOY転載
2023-04-22 14:37:081009ブラウズ

オブジェクトの公開

簡単に言えば、スコープ外のコードにオブジェクトへの参照を提供することです。たとえば、オブジェクトを返すか、それをパラメータとして他のクラスのメソッドに渡します。

安全でない公開オブジェクトの例:

<code>@Slf4j</code><code>@NotThreadSafe</code><code>public class UnsafePublish {</code><code><br></code><code>    private String[] states = {"a", "b", "c"};</code><code><br></code><code>    public String[] getStates() {</code><code>        return states;</code><code>    }</code><code><br></code><code>    public static void main(String[] args) {</code><code>        UnsafePublish unsafePublish = new UnsafePublish();</code><code>        log.info("{}", Arrays.toString(unsafePublish.getStates()));</code><code>        // 发布对象不安全,可被修改</code><code>        unsafePublish.getStates()[0] = "d";</code><code>        log.info("{}", Arrays.toString(unsafePublish.getStates()));</code><code>    }</code><code>}</code>

オブジェクト エスケープ

クラスが外部コードへのオブジェクト参照を提供し、構築が完了する前にオブジェクトを解放した場合、それはオブジェクト エスケープと呼ばれます。スレッドの安全性。

うわー

  • この内部クラスのインスタンスには、カプセル化されたインスタンスのプライベート ドメイン オブジェクトへの参照が含まれています。オブジェクトが正しく構築される前に解放されるため、安全でない可能性があります。これは、構築中にこの参照がオーバーフローする原因となるエラーです。

  • 上記のコードは、関数の構築中にスレッドを開始します。暗黙的起動でも明示的起動でも、この参照のオーバーフローが発生します。新しいスレッドは、構築される前に、所有するオブジェクトを常に参照します。

クラス名.thisの説明

「クラス名.this」の構文をJava言語では「修飾this」と呼びます。この構文の主な目的は、内部クラスのメソッドで、特定のネストされたレベルで外部クラスの「this」参照を指定する場合、「外部クラス名.this」構文を使用することです。例:

<code>public class Escape {</code><code>    private int thisCanBeEscape = 1;</code><code><br></code><code>    public Escape() {</code><code>        new InnerClass();</code><code>        // 还有业务需要执行</code><code>        thisCanBeEscape++;</code><code>    }</code><code><br></code><code>    private class InnerClass {</code><code>        public InnerClass() {</code><code>            log.info("{}", Escape.this.thisCanBeEscape);</code><code>        }</code><code>    }</code><code><br></code><code>    public static void main(String[] args) {</code><code>        new Escape();</code><code>    }</code><code>}</code>

Foo.Bar クラスの getFoo() メソッドで、「this」を直接記述すると Foo.Bar クラスのインスタンスを参照し、このインスタンスを指定したい場合は、ペリフェラル Foo クラス、ここでは Foo.this として記述する必要があります。特に、上記の例の getFoo() メソッドに Bar.this を記述すると、現在の Foo.Bar クラス インスタンスを指定してこれを直接記述するのと同じ効果が得られます。

オブジェクトを安全に公開する

  1. 静的初期化関数でオブジェクト参照を初期化する

  2. オブジェクト参照を揮発性型に保存するフィールドまたは AtomicReference オブジェクト

  3. 正しく構築されたオブジェクトの最終型フィールドにオブジェクトの参照を保存します

  4. オブジェクトの参照を保存しますロックで保護されたドメインへ

シングルトン モードのハングリー モード/レイジー モードを考えることができます。

安全な共有オブジェクト ポリシー

  1. スレッド制限: スレッドによって制限されたオブジェクトはそのスレッド専用であり、そのオブジェクトを所有するスレッドによってのみ変更できます。 。

  2. 共有読み取り専用: 共有読み取り専用オブジェクトは、追加の同期なしで複数のスレッドから同時にアクセスできますが、スレッドはそれを変更できません。

  3. スレッド セーフ オブジェクト: スレッド セーフ オブジェクトまたはコンテナは、同期メカニズムを使用して内部的にスレッド セーフを確保するため、他のスレッドは追加の同期なしでパブリック インターフェイスを介して自由にアクセスできます。

  4. 保護されたオブジェクト: 保護されたオブジェクトには、特定のロックを取得することによってのみアクセスできます。

以上がJava でオブジェクト エスケープの問題を公開して回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。