1

Threadpool executor のドキュメントを読んでいるときに、以下を参照してください。

提供されている 2 つのメソッド remove(java.lang.Runnable) と purge() を使用して、キューに入れられた多数のタスクがキャンセルされたときにストレージの再利用を支援できます。

タスクがキャンセルされた場合、これらのメソッドを使用してワーカー キューをクリーンアップできることを理解しています。実際のソースのどの部分がこのクリーンアップを自動的に行うのかを理解しようとしています。10 のキューで開始し、そのうち 4 つのタスクがキャンセルされ、新しいタスクが到着したときに、キューのサイズが 6 になるか、キャンセルされた 4 つのタスクを無視して 10 にリセットするとします。

ソースから、次のコメントが表示されます。

/**
 * Tries to remove from the work queue all
 * tasks that have been cancelled. This method can be useful as a
 * storage reclamation operation, that has no other impact on
 * functionality. Cancelled tasks are never executed, but may
 * accumulate in work queues until worker threads can actively
 * remove them. Invoking this method instead tries to remove them now.
 * However, this method may fail to remove tasks in
 * the presence of interference by other threads.*
 */ 
 public void purge() { 

しかし、ソース内のキャンセルされたタスクをワーカー スレッドがアクティブに削除する場所を教えてください。

お時間をいただきありがとうございます。

4

1 に答える 1

2

ワーカー スレッドは、ThreadPoolExecutor.getTask() でワーク キューからタスクを take() し、それらを run() しようとすると、通常の操作中にキャンセルされたタスクをアクティブに削除します。Runnable 作業単位を表す基礎となる FutureTask がその FutureTask$Sync.innerRun() を呼び出すと、最初に予想される READY 状態をチェックし、それ以外の場合は戻ります。そのため、タスクがキャンセルされ、workQueue から既に削除されている場合、実行はスキップされます。タスクがすでに実行中の場合、FutureTask.cancel() の mayInterruptIfRunning フラグによって、interrupt() が試行されるかどうかが決まります。

これは、デフォルトでは、キャンセルされたタスクは、利用可能なワーカーが処理を試み、タスクがキャンセルされたことを発見し、その処理を完了するまで、workQueue に留まることを意味します。したがって、キューのサイズに関する質問への答えは、ワーカーがこれらのタスクのいずれかに到達したかどうかによって異なります。ThreadPoolExecutor.purge() を使用すると、workQueue の即時トラバーサルを手動でトリガーして、キャンセルされたタスクを削除できます。

于 2013-08-05T23:21:31.063 に答える