JavaDoc for ThreadPoolExecutorBlockingQueue
は、エグゼキュータのバッキングにタスクを直接追加できるかどうかについては不明です。ドキュメントによると、呼び出しexecutor.getQueue()
は「主にデバッグと監視を目的としています」。
私はThreadPoolExecutor
自分でを構築していBlockingQueue
ます。キューへの参照を保持しているので、タスクを直接キューに追加できます。同じキューが返されるgetQueue()
ので、の警告はgetQueue()
、私の手段で取得したバッキングキューへの参照に適用されると思います。
例
コードの一般的なパターンは次のとおりです。
int n = ...; // number of threads
queue = new ArrayBlockingQueue<Runnable>(queueSize);
executor = new ThreadPoolExecutor(n, n, 1, TimeUnit.HOURS, queue);
executor.prestartAllCoreThreads();
// ...
while (...) {
Runnable job = ...;
queue.offer(job, 1, TimeUnit.HOURS);
}
while (jobsOutstanding.get() != 0) {
try {
Thread.sleep(...);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
executor.shutdownNow();
queue.offer()
vsexecutor.execute()
私が理解しているように、一般的な使用法は、を介してタスクを追加することですexecutor.execute()
。上記の私の例のアプローチには、キューをブロックするという利点がありexecute()
ますが、キューがいっぱいになり、タスクが拒否されるとすぐに失敗します。また、ジョブの送信がブロッキングキューと相互作用することも気に入っています。これは私にとってより「純粋な」生産者/消費者のように感じます。
キューにタスクを直接追加することの意味:呼び出す必要がありますprestartAllCoreThreads()
。そうしないと、ワーカースレッドが実行されません。エグゼキュータと他の相互作用がないと仮定すると、キューを監視するものはありません(ThreadPoolExecutor
ソースの調査によりこれが確認されます)。これは、直接エンキューのThreadPoolExecutor
場合、0を超えるコアスレッド用に追加で構成する必要があり、コアスレッドがタイムアウトできるように構成してはならないことも意味します。
tl; dr
次のようにThreadPoolExecutor
構成されている場合:
- コアスレッド>0
- コアスレッドはタイムアウトできません
- コアスレッドは事前に開始されています
BlockingQueue
遺言執行者の支援への参照を保持する
呼び出す代わりに、タスクをキューに直接追加することはできますexecutor.execute()
か?
関連している
この質問(プロデューサー/コンシューマーワークキュー)も同様ですが、キューに直接追加することについては特に説明していません。