私が次のことをすると言う...
//MyRunnable は私が宣言したクラスで、Runnable を実装しています。
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r = null;
上記のコード スニペットのように r を null に設定すると、どのような影響がありますか?
私が次のことをすると言う...
//MyRunnable は私が宣言したクラスで、Runnable を実装しています。
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r = null;
上記のコード スニペットのように r を null に設定すると、どのような影響がありますか?
これを図で説明しましょう。
1-で
MyRunnable r = new MyRunnable();
MyRunnable
主にインターフェースを実装するクラスの新しいインスタンスを作成していRunnable
ます:
2-で
Thread t = new Thread(r);
新しいスレッドを作成し、参照 r が指しているオブジェクトを値渡ししています。
3-で
r = null;
スレッドを実行するために Thread が使用している r 参照とMyRunnable
オブジェクトの間のリンクを削除しています。t
影響はありません。
スレッドはすでに開始されています。それに関係なく、スレッドオブジェクトは参照を保持するため、ガベージコレクションが行われるまでガベージコレクションは行われt
ません。
何もない。
変数r
はオブジェクトそのものではありません。これは、コード ブロック内のそのオブジェクトへMyRunnable
の単なる参照です。
最初に、新しいMyRunnable
オブジェクトを作成します。次に、「名前を付ける」/変数に割り当てますr
。次に、それをコンストラクターに渡しますThread
(変数を使用して、話しているオブジェクトを記述します)。そのコンストラクター内では、ほぼ確実に他の参照に割り当てられます (私が使用している JDK では、それは と呼ばれるフィールドですtarget
)。
後で、r
別のオブジェクト (この場合はオブジェクト) で参照を再ポイントしnull
ます。これは、それを指すために使用したオブジェクトには何の影響も与えません。参照だけです。同様に、同じオブジェクトを指している他の参照には影響しません。
したがって、Thread.target
参照は最初に作成した同じオブジェクトを指し続けMyRunnable
、スレッドの観点からは何も変わっていません。
唯一の潜在的な違いは、(外側の) コード スニペットに、それが作成したオブジェクトへの参照がなくなったことです。したがって、次のコードは、そのオブジェクトのメソッドを呼び出すことも、メソッド引数などとして渡すこともできません. )
特定のオブジェクトへの参照を保持するものが何もない場合、ガベージ コレクターは次回の実行時にそのオブジェクトを到達不能と見なし、収集します。ただし、オブジェクトへの参照がなければ、オブジェクトに対して何もできないため (GC の背後にある原則全体)、これについて心配する必要はほとんどありません。
この場合、はまだ参照を保持しているMyRunnable
ため、GC されませんThread
。
つまり、コンストラクターの動作が異なり、参照が必要ないために参照を格納しない場合 (単に表現を使用するだけかもしれません)toString()
、オブジェクトは到達不能と見なされ、収集されます。どちらの場合も、ガベージ コレクターは正しいことを行います。オブジェクトを参照するものがなくなった場合に限り、オブジェクトを収集します。コードでそれについて心配したり知ったりする必要はありません。