6

以下のコードでスレッドリークの理由を見つけるのを手伝ってください。TestThreadrun()が完了し(コンソール印刷ステートメントから確認)、mainメソッドが終了した(印刷ステートメントとプロファイラーツールから確認)後でも、はガベージコレクションを取得しません。

ただし、TestThreadデーモンスレッドとして設定されている場合、ガベージコレクションが行われt.setDaemon(true)ます。以下のコードは、私のアプリケーションの問題を説明するサンプルコードです。既存のスケジューリングクラス(他の誰かが使用して設計したものScheduledExecutorService)を使用しようとしています。Runnableクラスで複数のをスケジュールし続けると、作成されたスレッドがガベージコレクションされないことに気付きました。

public class ThreadTest {

  static void runThreadWithExecutor() {
    final String name = "TestThread";
    ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor(
        new ThreadFactory() {
          @Override
          public Thread newThread(Runnable r) {
            Thread t = new Thread(r, name);
            t.setDaemon(false);
            return t;
          }
        });

    ses.schedule(new Runnable() {
        @Override
        public void run() {
           System.out.println("entered " + name);
           System.out.println("exiting " + name);
        }},
      2,
      TimeUnit.SECONDS);
    }

  public static void main(String[] args) throws InterruptedException {
    System.out.println("entered main");
    runThreadWithExecutor();
    Thread.sleep(5000);
    System.out.println("exiting main");
  }
}
4

2 に答える 2

5

shutdown()これは、最後のジョブをスケジュールした後でエグゼキュータ サービスを呼び出していないためです。

ses.schedule(...);
// this stops any management threads but existing jobs will still run
ses.shutdown();

shutdown()コードに呼び出しを追加したところ、正常に終了しました。これはすべてExecutorServiceの s に当てはまります。シャットダウンしないと、スレッド プールはさらにジョブが送信されるのを待ち続け、GC されることはありません。

詳細については、以下の @John の回答を参照してください。

于 2012-05-17T16:00:43.427 に答える
3

@Grayは彼の評価で正しいと思います.彼が正しい理由を追加すると思います. ExecutorService は、スレッドを再利用するスレッドプールです。

run メソッドが完了するときとは異なりnew Thread(runnable).start();、スレッドは完了してから GC されます。Executor Runnable が完了すると、スレッドはそこに留まり、別の実行可能なタスクが送信されて使用されるのを待ちます。したがって、シャットダウンすることで、エグゼキュータにスレッド プール内のすべてのスレッドを終了するように指示することになります。

あなたの最後の部分に答えるために。デーモンに設定すると、他の (デーモン以外の) スレッドが実行されていないためにのみ機能します。アプリケーションが他の非デーモン スレッドを開始した場合、Executor スレッドは続行されます。デーモン スレッドのみが実行されている場合、デーモン スレッドは強制終了されることに注意してください。

于 2012-05-17T16:10:56.023 に答える