The King's Museum

ソフトウェアエンジニアのブログ。

『Javaの理論と実践: スレッド・プールとワーク・キュー』のメモ

スレッド・プールとワーク・キュー

記事:Javaの理論と実践: スレッド・プールとワーク・キュー

メモ:

  • サーバーアプリケーションは「処理時間の短いタスク・大量のタスク」を処理することが多い
  • これに対して、スレッドを都度立ち上げるというマルチスレッド化をすると、、、
    • タスク処理時間は短いので、スレッドの生成・破棄のオーバーヘッドの割合が大きい
    • タスクの数が多いので、スレッドが際限なく立ち上がることがあり、メモリ不足・スラッシングなどに陥る
  • サーバーアプリケーションでは、スレッドプールが良い解決策となる
    • 各タスクにオーバーヘッドが分散する(都度たちあげないから)
    • スレッド数を制限することができる
  • スレッドプール以外の方法
    • スレッド都度立ち上げ方法
    • 単一のバックグラウンドスレッドとワークキュー(UI 方式)
  • スレッドプールという名称は現実と乖離している
    • 実装の形態は「プール」という言葉でイメージするものと違う
    • 実際、そういう実装をするとプールが空のときにクライアントのブロックを引き起こしてしまう
    • 現実は「ワークキューと対応する固定数のスレッドグループ」
  • スレッドプールのリスク
    • デッドロック:あるタスクが他のタスクの完了を待つ場合
    • リソース・スラッシング:スレッドプールが大きすぎる場合
    • 平行性エラー:悪名高い notify() と wait() => util.concurrent を使う
    • スレッド漏出:タスク内例外をハンドルせず、スレッドが戻ってこなくなる場合
    • 要求のオーバーロード::要求がキューにたまりすぎたときの対応は考えておく
  • スレッドプールが効果的であるための条件
    • 他のタスクの完了を同期するタスクをキューにいれない
    • 長時間実行オペレーションのタスクをいれるさいは最大待ち時間を指定する
    • タスクの制約(CPU?IO?)を理解する
  • プールサイズの調整も CPU 制約か IO 制約かで変わる
  • むやみにスレッドプールは自作しない
    • concurrent.PooledExecutor クラス を使うこと

感想

そういえば昔、Coursera の『Pattern-Oriented Software Architectures for Concurrent and Networked Software』でスレッドプール+ワークキューの実装に複数種類があるということを学んだのだけど、失念して思い出せない、、、。

Pattern-Oriented Software Architectures for Concurrent and Networked Software

今度、ちゃんと勉強しなおして記事にしよう・・・

(c) The King's Museum