サーブレットは『クライアントからのリクエストに応じて処理を行ってレスポンスを返すクラス』です。ですが、最初の起動時に生成された1個のインスタンスですべてのリクエストを処理します。
「次は複数のリクエストがあった場合の処理イメージです」
「そもそも何のために『インスタンスは1つだけ』にするんですか?」
「メモリを節約するためです。クライアントからアクセスがあるたびにインスタンスを生成していると、アクセス数が増えるととたんにメモリリーク(使用可能なメモリ領域がなくなること)を起こし、処理が止まってしまいます。無限のメモリ領域を用意できればリクエストごとにインスタンスを生成すればいいのですが、そういうわけにもいきません。Web上で運用することを考えれば、クライアントごとに1つのインスタンスを与えるのではなく、生成済みのインスタンスを活用してすべてのクライアントに対応することが必要なのです」
シングルインスタンス・マルチスレッド
「メモリ不足にならないように『スレッド』なんたらってのを使ってるようですね」
「まず、クライアントAがServlet01をリクエストしたとします。Servlet01はJSP/サーブレットコンテナーによってインスタンス化されます。すると同時にAというスレッドが生成されます。これはクライアントAとServlet01を繋ぐ窓口になります」
「『窓口』って。いわれても何かピンときませんが、クライアントAはスレッドAを通じてServletとやり取りするということですね」
「そうです。なので、クライアントAへのレスポンスはスレッドAから返されます。以降は、クライアントAからのリクエストはスレッドAを通じて処理されることになります」
「じゃ、次のクライアントBもCもServlet01をリクエストしたら、スレッドBが生成され、スレッドを通じてやり取りが行われるわけですね。確かにインスタンスは1つだけですが、その代わりクライアントのぶんだけスレッドが生成されるので、結局同じことじゃないですか」
「ポイントは『スレッドには中身がない』ってことです。あくまでインスタンスに関連付けられたメソッドを呼び出したり、フィールドを参照したりするだけの『小さなプログラム』です。で、先程『クライアントのぶんだけスレッドが生成される』といいましたが、正確には『あらかじめ用意されたスレッドを使う』のです。スレッドの生成にもそれなりのコストがかかるので、アプリケーションサーバーはあらかじめいくつかのスレッドを『スレッドプール』として用意しています」
「スレッドの『溜り場』みたいなもんですね。そこからスレッドを取り出してクライアントにあてがうわけだ」
「もちろん、スレッドを生成させるコードを書く必要はありません。サーブレットを呼び出せば、自動的にスレッドが割り当てられるのですね。で、『1つのサーブレットから生成されたスレッドはメモリ空間を共有する』ということになるのです」
「クライアントAもBもCも、みんな同じメモリ空間に存在するインスタンスを使うってことですね」
Copyright © ITmedia, Inc. All Rights Reserved.