3

メソッド内でローカル スレッドを宣言するとどうなるのだろうか。通常、ローカル変数はすべてスタックに割り当てられているため、関数が戻るとすぐにすべてなくなります。ただし、ローカル スレッドは別の話になるようです。そうですか?

public int A() {
    Thread t = new Thread() {
        doSomething();
    }
    t.start();
    return -1;
 }
4

5 に答える 5

7

ジョンの答えは良いですが、さらに詳細を追加したいと思いました。これは、特定の変数の使用法を示すために使用するコード例です。

 public void startThread() {
      long var1 = 10;
      byte[] var2 = new byte[1024];
      final byte[] var3 = new byte[1024];
      final byte[] var4 = new byte[1024];
      Thread thread = new Thread(new Runnable() {
          private long var5 = 10;
          private byte[] var6 = new byte[1024];
          public void run() {
              int var7 = 100;
              byte[] var8 = new byte[1024];
              System.out.println("Size of var4 is " + var4.length);
              baz();
              ...
          }
          private void baz() {
              long var9 = 2;
              byte[] var10 = new byte[1024];
              ...
          }
      });
      thread.start();
 }

したがって、ここではスレッドに割り当てられた多数の変数があります。Threadオブジェクト自体Runnableと、スレッドが実行しているターゲットもあります。

  • スレッド -- ローカルにあるように見えますがstartThread()、関連付けられThreadている も JVM によって管理されます。run()メソッドが終了Threadし、JVM によってリープされた後にのみ GCされます。が GC された後、Threadによって使用されるすべてのフィールドをThreadGC することができます。
  • Runnable -- この匿名クラスは、スレッドが実行しているものです。終了後にGCすることができ、GCされThreadます。
  • var1 -- これはローカルでstartThread()あり、スタックに割り当てられています。startThread()メソッドが終了し、スタックが再利用されると上書きされます。
  • var2 -- これはローカルでstartThread()あり、ヒープに割り当てられます。ではないため、スレッドでは使用できませんfinal。終了後にGCすることができますstartThread()
  • var3 -- これはローカルでstartThread()あり、ヒープに割り当てられます。これは、スレッドで使用できるfinalようにするためですが、そうではありません。終了後にGCすることができます。startThread()
  • var4 -- これはローカルでstartThread()あり、ヒープに割り当てられます。これはfinal、スレッドによって使用されます。startThread()メソッドが終了Runnableとが GC された後にのみ GC できますThread
  • var5 -- これは、匿名クラスRunnableの一部としてヒープに割り当てられた内部のローカル フィールドです。終了Runnable後に GC することができ、およびが GC されます。RunnableRunnableThread
  • var6 -- これはRunnable、ヒープに割り当てられた内部のローカル フィールドです。Runnable終了後に GC することができ、RunnableおよびThreadが GC されます。
  • var7 -- これはrun()メソッド内のローカル フィールドであり、新しいスレッドのスタックに割り当てられます。run()メソッドが終了し、スタックが再利用されると上書きされます。
  • var8 -- これはrun()メソッド内のローカル フィールドで、ヒープに割り当てられます。run()メソッドの終了後に GC できます。
  • var9 -- これはbaz()メソッド内のローカル フィールドで、新しいスレッドのスタックに割り当てられます。baz()メソッドが終了し、スタックが再利用されると上書きされます。
  • var10 -- これはbaz()メソッド内のローカル フィールドで、ヒープに割り当てられます。baz()メソッドの終了後に GC できます。

その他の注意事項:

  • 新しいスレッドが開始されていない場合は、終了後に GC できますstartThread()。それRunnableに関連付けられているすべての変数を GC することもできます。
  • final long varXスレッドでプリミティブを宣言して使用する場合は、スタックではなくstartThread()ヒープに割り当てる必要があります。終わってもまだまだ使えます。startThread()
于 2012-05-11T16:24:56.140 に答える
0

変数がプリミティブの場合、スタック上にあり、メソッドが戻ると消えますが、スレッドのRunnableインスタンス (またはスレッドの肉を含むもの) には、そのプリミティブ値のコピーがあります。

変数が参照型の場合、オブジェクトはヒープに割り当てられ、それへの参照がなくなるまで存続し、その時点でガベージ コレクションの対象となります。そのオブジェクトへの参照はスタック上にあり、メソッドが戻ると消えますが、プリミティブと同様に、スレッドRunnableには同じ参照のコピーがあります (したがって、そのオブジェクトは生きたままになります)。

于 2012-05-11T15:49:08.370 に答える
0

runThread がローカル コンテキストから開始された場合、スレッドは Runnable のメソッドの実行が完了するまで実行を続けます。

于 2012-05-11T15:46:19.133 に答える