[解決済み] サイズ制限のあるキャッシュスレッドプールの作成は不可能?
質問
作成できるスレッド数に制限のあるキャッシュスレッドプールを作成することはできないようです。
以下は、静的な
Executors.newCachedThreadPool
が標準的なJavaライブラリでどのように実装されているかを示します。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
というわけで、このテンプレートを使って、固定サイズのキャッシュされたスレッドプールを作って行くことにします。
new ThreadPoolExecutor(0, 3, 60L, TimeUnit.SECONDS, new SynchronusQueue<Runable>());
さて、これを使って3つのタスクを投入すると、すべてうまくいきます。 それ以上のタスクを投入すると、実行拒否の例外が発生します。
これを試してみてください。
new ThreadPoolExecutor(0, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runable>());
この場合、すべてのスレッドが順次実行されることになります。 つまり、スレッドプールはあなたのタスクを処理するために複数のスレッドを作成することはありません。
の execute メソッドにあるバグです。
ThreadPoolExecutor
? それとも、これは意図的なものなのでしょうか? それとも他に方法があるのでしょうか?
編集: 私はキャッシュされたスレッドプールのようなもの (必要に応じてスレッドを作成し、あるタイムアウトの後にそれらを終了させる) が欲しいのですが、作成できるスレッドの数に制限があり、スレッドの制限に達した後に追加のタスクをキューに入れ続ける機能があります。 sjleeの回答によると、これは不可能だそうです。 を見ると
execute()
メソッドを見ると
ThreadPoolExecutor
を使用することは、確かに不可能です。 私はサブクラスで
ThreadPoolExecutor
をオーバーライドして
execute()
のように
SwingWorker
がそうであるように、しかし
SwingWorker
はその
execute()
は完全にハックされています。
どのように解決するのですか?
この
ThreadPoolExecutor
には以下のようないくつかの重要な動作があり、あなたの問題はこれらの動作で説明することができます。
タスクが送信されたとき。
- スレッドプールがコアサイズに達していない場合、新しいスレッドを作成します。
- コアサイズに達しており、アイドルスレッドがない場合、タスクをキューに入れます。
- コアサイズに達し、アイドルスレッドがなく、キューが一杯になった場合、新しいスレッドを作成します(最大サイズに達するまで)。
- 最大サイズに達し、アイドルスレッドがなく、キューが一杯になった場合、拒否ポリシーが起動します。
最初の例では
SynchronousQueue
は本質的に 0 のサイズを持っています。したがって、最大サイズ (3) に達した瞬間に拒否ポリシーが作動します (#4)。
2 番目の例では、選択されたキューは
LinkedBlockingQueue
であり、サイズは無制限です。 したがって、2番目の動作で行き詰まります。
キャッシュ型や固定型は挙動がほぼ決まっているため、あまりいじることができません。
もし、制限された動的なスレッドプールを持ちたいのであれば、有限サイズのキューと組み合わせた、正のコアサイズと最大サイズを使用する必要があります。 たとえば
new ThreadPoolExecutor(10, // core size
50, // max size
10*60, // idle timeout
TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(20)); // queue with a size
追記 : これはかなり古い回答で、コアサイズ0に関してはJDKが動作を変更したようです。 JDK1.6以降、コアサイズが0でプールにスレッドがない場合、ThreadPoolExecutorはそのタスクを実行するためにスレッドを追加することになります。したがって、コアサイズ0は上記のルールの例外となります。感謝 スティーブ に対して 持ってくる を知らせてくれてありがとう。
関連
-
ファインバグタイプ
-
Spring BootのテストメソッドFailed to load ApplicationContextの問題を解決する
-
xxx:jarのアーティファクトディスクリプタの読み込みに失敗した問題は解決しました。
-
マスキング このリソースにアクセスするには、完全な認証が必要です。
-
javaでよく使われる英単語
-
mavenプロジェクトのテストエラー java.lang.ClassNotFoundException: org.glassfish.jersey.client.ClientConfig の問題を解決する。
-
SocketTimeoutExceptionです。読み込みがタイムアウトしました
-
コミットには何も追加されないが、未追跡のファイルが存在し、gitで未追跡のファイルに対する完璧な解決策
-
[解決済み] Java 8 の並列ストリームにおけるカスタムスレッドプール
-
[解決済み] fork/joinフレームワークはスレッドプールより優れているか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
この行に複数のマーカーがある - HttpServletResponseが型エラーに解決できない
-
Dateが型に解決できない問題を解決する
-
Eclipseで "XXXX "の解決策を(型に)解決することができない
-
Javaクラスローダーにソースコードから潜り込む
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
スレッド "main" で例外発生 java.lang.ArrayIndexOutOfBoundsException: 0 at One1.main(One1.java:3)
-
自動配線された依存性のインジェクションに失敗しました。
-
JSPで「リストが型解決できない!」の解決方法
-
Java(1)仕上げの基本概念+eclipseのインストール構成
-
このラインで複数のマーカーを解決する方法