サーブレットのライフサイクル
①initメソッド
②serviceメソッド
・doGetメソッド
・doPostメソッド
※リクエストの種類に応じて、呼び分けられる。
③destroyメソッド
上記、各メソッドをオーバーライドすることで、各メソッドの呼び出しタイミングで任意の処理をさせることができる。
シングルインスタンスとマルチスレッド
サーブレットは
・各リクエストに対し、すでに生成した1つのインスタンスを再利用する。都度、インスタンスは生成しない。
・複数リクエストに対しては、マルチスレッドで並行処理を行う。
※マルチスレッドで動作するため、スレッド間で共有されるインスタンス変数や、クラス変数の取り扱いには注意が必要。
具体的には、2リクエストが同時に変数を取得し、更新を行うと、意図しない値に更新されるなど。
上記問題の対策としては、片方のリクエストが値を設定するまで、もう片方のリクエストから値を取得するのを待機させる。
これを排他制御という。
また、マルチスレッドで並行に実行しても正常に動作することを、スレッドセーフという。
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter pw = resp.getWriter(); Page.header(pw); // プロック内の処理を同時に実行できるスレッドを1つだけに制限 synchronized(this) { int i = count; try { Thread.sleep(3000); } catch(InterruptedException e) {} count = i+1; pw.println(count); } Page.footer(pw); }