3

別の電子メール アドレスに電子メールを送信する Java プロセスがあり、Java スレッド プール エグゼキュータを使用しています。各スレッドは電子メールを送信しようとして終了します。

問題は、すべてのスレッドが待機状態になり、スレッドが正常に動作を完了しても実行状態に戻ることができないことです。

私のthreadPoolExecutor構成は次のとおりです。

キューサイズ = 100 スレッド数 = 5 最大スレッド数 = 10 キープアライブ時間 = 1 分

ここにスレッドダンプがありますが、何を言っているのかわかりませんでした

java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x2808f538> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(Unknown Source)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(Unknown Source)
    at java.util.concurrent.ArrayBlockingQueue.take(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.getTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

   Locked ownable synchronizers:
    - None

コードは次のとおりです。

ReqtQueue = new ArrayBlockingQueue<Runnable>(100, true);
        notifTaskExecutor   = new ThreadPoolExecutor(
          5, // core size of threads that will remain in idle state
          10, // max size of thread that can be created
          1, // keep alive time for thread other than number of core threads when they are in idel state
          TimeUnit.MINUTES, // keep alive time units
          ReqtQueue // the queue to use
        );

そして、execute メソッドが呼び出されます。

notifTaskExecutor.execute(new NotificationSender(request, name));

NotificationSender はメールを送信するだけで、すべてのコードは try catch にあり、非常に単純です。run メソッドが空の場合でも、スレッドは終了しません。

助けが必要

よろしく

4

1 に答える 1

6

スレッド ダンプを見ると、スレッドはタスク キューでさらにタスクを待機しています。つまり、これは予期される動作です。

JVM は、すべての非デーモン スレッドが終了し、スレッド プールが非デーモン スレッドを使用する場合にのみ終了します。

スレッド プールをシャットダウンするには、スレッド プールで shutdown() メソッドを呼び出す必要があります。すでに送信されたタスクはシャットダウンする前に処理されるため、タスクを送信した直後にこのメソッドを呼び出すことができます (shutdownNow メソッドとは異なります)。

または、デーモン スレッドを使用するスレッド プールを使用することもできます。最後の非デーモン スレッドが終了すると、これらは自動的にシャットダウンします。

しかし、あなたの場合、シャットダウン方法を使用したいと思います。ログメッセージなどを出力するために、shutdown を呼び出した後に awaitTermination メソッドを呼び出して、タスクが終了するのを待つこともできます。

于 2012-09-14T07:53:31.700 に答える