ThreadPoolExecutor バック タスク実行モジュールがあります。一部のタスクはアプリケーション コードで終了しているように見えますが、ワーカー コードは何らかの理由で try/catch/finally をすべてスキップして次のタスクを取得するだけで、前のタスクで重要なステータス レポート コードが失われています。
この例のように、257832:5 はスレッド 8 によって取得されましたが、このスレッドは最終的に別のタスクを開始するだけです。
2012-07-11 15:53:39,389 INFO [pool-1-thread-6]: タスク (258861:5): 開始しています。 2012-07-11 15:53:39,389 情報 [pool-1-thread-6]: ### を実行しているタスクがアプリ ロジックによってログに記録されました 2012-07-11 15:54:18,186 INFO [pool-1-thread-6]: タスク (258868:5): 開始しています。### 突然別のピックアップ ! 2012-07-11 15:54:18,186 情報 [pool-1-thread-6]: ### を実行しているタスクがアプリ ロジックによってログに記録されました 2012-07-11 15:54:18,445 情報 [pool-1-thread-6]: タスク (258868:5): Task.doWork から返されました。 2012-07-11 15:54:18,446 INFO [pool-1-thread-6]: タスク (258868:5): ファイナライズ中。 2012-07-11 15:54:18,487 INFO [pool-1-thread-6]: タスク (258868:5): ステータス結果の通知: 200。 2012-07-11 15:54:18,487 INFO [pool-1-thread-6]: タスク (258868:5): 完了
ThreadPoolExecutor の Runnable は正常に見えます。のように見えます
public void run() {
log.info(String.format("Task (%s:%s) : Starting.", wfId, taskId));
try {
Object result = task.doWork(...); // call the application codes
log.info(String.format("Task (%s:%s) : returned from Task.doWork.", wfId, taskId));
status = "DONE";
} catch (Throwable t) {
log.error("Error executing task: " + taskId + " - " + className);
} finally {
log.info(String.format("Task (%s:%s) : finalizing.", wfId, taskId));
// notify status to a server
log.info(String.format("Task (%s:%s) : Finished", wfId, taskId));
}
}
// the task framework looks like
// Use a queue size larger than numThreads, since the ThreadPoolExecutor#getActiveCount() call only returns an approximate count
this.executor = new ThreadPoolExecutor(numThreads, numThreads, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(numThreads * 2));
executor.execute(new TaskRunnable(...));
ノート:
- 究極の Throwable をキャッチしますが、2 つのタスク間でログに記録される例外はありません
- exit() が呼び出されたり、プログラムが再起動したりする兆候はありません
- 最初のものはすべてのログ行をスキップしました。これは、アプリ コードへの呼び出しの直後か、catch 内のものか、最終的にブロックされたものかに関係なく、ステータス レポート コードをスキップします。
- これは低い確率でランダムに発生します。しかし、実行されるタスクの数が多いため、依然として多くの頭痛の種になります。
これは、スレッド プール エグゼキューターが実行中の実行可能オブジェクトを魔法のように単純に削除するかのように発生します (そうしないと、Throwable としてキャッチされる InterruptedException が必要になります。Java スレッドは、シャットダウン/終了中を除き、非協調的に停止されません)。ブロック。ThreeadPoolExecutor javadoc を確認しましたが、そのようなイベントが発生することはありません。
何が起こったのでしょうか?