スレッドプール復習
Web、ファイル、メール、データベースなどのサーバで動くプログラムは一般的に処理要求数が多く、各処理時間が短い。
そして、同時要求や割り込みなど様々な要因から、一般的にはスレッドで処理が行われる。
しかし、スレッドを要求を受けるたびにスレッドの生成・破棄を繰り返していると、サーバのリソースを大量消費し、効率が悪くなる。
それを解決するために、「スレッドプール」という方法がある。
自作HTTPサーバから抜粋。
for(int i=0;i<numThreads;i++) { requestProcessor req=new requestProcessor(dir); Thread t=new Thread(req); t.start(); }
for文でnumThreads数(通常10前後)だけスレッドを生成・スタートさせて、以降の文で
while(true) { try { Socket sock=servsock.accept(); requestProcessor.reqProc(sock); }catch(IOException e) { e.printStackTrace(); } }
とすれば、接続要求を出したクライアントのソケットの情報を持って、サーバ側の処理がスレッド内で行われる。スレッドは待ち行列によって管理され、1つスレッドが終了すると次のスレッドが実行されるというサイクルを繰り返す。
Runnableを実装したrequestProcessorクラス内ではsynchronized、wait、notify(notifyAll)などを使って、デッドロックや矛盾を防止する仕組みが必要である。ただし、notifyとnotifyAllについては処理の仕組みによって効率が異なるので注意が必要。
スレッドプールを使用する際の注意点を挙げると、
スレッドプールと同様の方法に「ワークキュー」がある。
参考:IBM Developer 日本語版 : 大変申し訳ありません。このページは無効です。
普通のアプリケーションを作る時には、スレッドについては1人のユーザ視点の検討で済んだが、サーバプログラムとなるとそうもいかない。もっと「方法」を知らないとヤバイかも。方法を作るのは時間が掛かり過ぎるし、知ってないと使いようが無いからな。