2011-12-13 6 views
0

は、私は、ネストされたクラスを使用して、新しいスレッドを開始し、このTestクラスのインスタンスを作成するとしますGCを別のスレッドで使用しても、ここで変数を収集できますか?

public class Test 
{ 
    private String _str; 

    public Test() 
    { 
     _str = "Hello world !"; 
     new TestThread().start(); // Start a background thread 
    } 


    private class TestThread extends Thread 
    { 
     public void run() 
     { 
      while (true) 
      { 
       System.out.println(_str); 
       Thread.sleep(1000); 
      } 
     } 
    } 
} 

私は私のTestインスタンスへの強い参照を削除する場合は、今どうなりますか?バックグラウンドスレッドはまだ生きており、変数_strを印刷し続けますが、GCがいつでもその値を収集できることは恐れています。

もちろん、参照のローカルコピー(コンストラクタ:public TestThread(String str)を使用してローカル変数に格納)を作成できますが、これが必要かどうかは疑問です。 Testから強い参照を有する

答えて

5

TestThread自体が、そうであれば回収可能でないように、Testのインスタンスが収集可能ではありません。実行中のスレッドなので、TestThreadのインスタンスは明らかに収集できません。

静的でない内部クラス(TestThread)を作成すると、そのクラスのすべてのインスタンスは、包含クラス(Test)のインスタンスへの暗黙の参照の暗黙の参照を持ちます。

Nested Classes Java Tutorialの内部クラスセクションを参照してください。

GCが行うことを「恐れている」必要はありません。あなたが弱い参照で作業するつもりでない限り、あなたが参照できるオブジェクトを収集しません。

1

gcについて心配する必要はありませんが、_strのメモリの可視性は保証されません。

TestThreadに正しい値が表示されるようにするには、_strが必要です。また、コンストラクタの後でスレッドを開始する必要があります。現在のコードでは、コンストラクタが完了する前に別のスレッドからこのポインタにアクセスできるため、finalに対する保証は無効になります。

最終的な変数としてTestThreadに(前述のように)_strのコピーを格納してから、TestThreadを静的なクラスにすると、このすべてが解決されます。

関連する問題