Object Poolパターン
Object Poolの利用シーン
データベースのコネクションプールを例にObject Poolの必要性とメリットを説明しました。このほかに、Webコンテナにおけるサーブレットのスレッド自体もスレッドプールというObject Poolが利用されています。また、EJBコンテナでは、仕様としてEJBオブジェクトをプールして再利用するObject Poolがあります。さらにDIコンテナでは、多数のオブジェクトの利用を管理する際に、Object Poolが実装されています。
Object Poolの利用は、こうしたコンテナやフレームワークだけでなく、独自のアプリケーションでも必要になる場面が結構あります。例えば大量にメールを配信する処理を行いたい場合などでは、メールを配信するオブジェクトでObject Poolを利用することで、スループットの向上やネットワークの帯域、接続数などを考慮することができます。それ以外にも、ログファイルなどの大量のファイルアクセスを行う場合には、ファイルアクセスを行うオブジェクトをObject Poolにした方が、OS上の同時ファイルアクセス数やディスクへの入出力を考慮してチューニングすることができます。
Object Poolは、メモリやディスク、ネットワークなどの限られたリソースを利用する処理で利用されることが多いため、Resource Poolというパターンで説明されている場合もあります(*3)。
*3:Resource Poolパターンは、「Data Access Patterns」(Nock Clifton. Boston:Addison-Wesley)という書籍で紹介されています。
Object Poolパターンの概要
図2にObject Poolパターンの一般的な構造を示しました。また、下表にObject Poolの目的、問題、構成要素、関連するパターンを整理しておきました。
・目的
オブジェクトの生成にコストがかかる場合などで、オブジェクトの数を制限して再利用を管理する。
・問題
特定の規則に沿った、オブジェクトの生成を管理する。オブジェクトの数や、オブジェクトの取得と利用、利用が終了したオブジェクトの再利用などについて管理が必要となる。
・構成要素
Reusable Poolは、Clientによって利用されるReusableオブジェクトの利用を管理する。Clientは、Reusable Poolからオブジェクトを取得して、利用する。Reusable PoolによってすべてのReusableオブジェクトが保持されているため、統一した方法で管理できる。
・関連するパターン
Singleton
ReusablePool自体は通常Singletonパターンでオブジェクトを1つに制限する。
Factory Method
オブジェクトの生成では、Factory Methodが利用されることが多い。Factory Methodでは、生成のみを管理しその後のオブジェクトの管理はPoolが行う。
Clientは、Reusableオブジェクトが必要となったときに、Reusable PoolのacuireObjectを呼び出し、Reusableオブジェクトを取得します。acuireObjectメソッドは、プールから利用可能な(未使用の)オブジェクトを割り当てて返し、オブジェクトを利用中としてマークします。プールに利用可能なオブジェクトがない場合、新たにインスタンスを生成して返します。オブジェクト数が上限に達していて生成できない場合、オブジェクトがプールに返されるまで待つか、または、取得失敗のエラーを返します。
Clientは、Reusableオブジェクトが不必要になった(利用が終了した)ときに、Reusable PoolのreleaseObjectにReusableオブジェクトを引数として呼び出し、Reusableオブジェクトを開放します。releaseObjectメソッドでは、プールにオブジェクトを戻し、利用可能な状態にします。releaseObjectメソッドに相当する開放メソッドを、Reusableオブジェクト自身に実装する方法もあります(コネクションプールの場合のConnection#close()メソッドがこれに相当します)。