1

次のシナリオを検討してください。

  • オブジェクトは、ある関数でローカルmyObjにインスタンス化されます。myFunc
  • myObjsomeThreadソケットからの読み取りなど、バックグラウンドタスクを実行するスレッドを開始します。
  • myFuncその後、戻り、myObj逆参照されます。

通常の状況では、JVMはガベージコレクションを行うだけmyObjです。ただし、someThreadがまだ実行されている場合、これは引き続き当てはまりますか?

まだ実行されている限り、someThreadそれ自体はGCされないことを理解していますが、私のコードでは、に格納されている値にもアクセスする必要があるため、実行中も存続myObjすることを確認することが重要です。myObj

4

1 に答える 1

3

オブジェクトへの参照がない場合にのみ、オブジェクトはガベージコレクションの対象になります。someThreadに格納されている値にアクセスする必要があると言います。myObjつまり、への参照が必要です。これは、資格がない限り、ガベージコレクションの資格がないことを意味します。myObjmyObjsomeThread

オブジェクトがあなたの下からガベージコレクションされないことを保証できるので、たとえば、これは完全に安全です。

void foo() {
    final Object something = new String("I'm alive!");
    new Thread() {
        public void run() {
            try {Thread.sleep(10000);} catch (InterruptedException e) {}
            System.out.println(something);
        }
    }.start();
}

somethingは匿名スレッドによって参照されるため、匿名スレッドが完了するまでガベージコレクションの対象にはなりません。

より具体的にあなたの例では、これも安全です:

void foo() {
    new ThreadStartingObject("I'm alive!");
}

class ThreadStartingObject {
    private String message;

    public void ThreadStartingObject(String msg) {
        this.message = msg;
        new Thread() {
            public void run() {
                try {Thread.sleep(10000);} catch (InterruptedException e) {}
                System.out.println(message);
            }
        }.start();
    }
}

スレッドを表す匿名の内部クラスには、外部への暗黙の参照this、つまりのインスタンスがありThreadStartingObjectます。その参照はガベージコレクションを防ぎます。

于 2012-08-26T01:14:40.927 に答える