///////////////////////////////////////////////////////////////////////////////
//  << sv161b.java >>
//
// サーブレット(6):応用(アクセスカウンタ 実験)
//
//  2つのWebブラウザから同時にサーブレット(sv161b.java)を起動し、それぞれ
//  3000回アクセスし、アクセス回数に矛盾が生じないか調べる。
//
// ●起動法
//  (1)Javaファイル(sv161b.java)をコンパイルし、classファイル(sv161b.class)を
//       作成する。
//       ただし、Javaファイル(sv161b.java)は、
//       %CATALINA_HOME%\webapps\SV\WEB-INF\classes\sv161b.java
//     classファイル(sv161b.class)は、
//       %CATALINA_HOME%\webapps\SV\WEB-INF\classes\sv161b.class
//       に保存する。
//    (2)入力フォームで、
//         URL(http://localhost:8080/SV/servlet/sv161b)
//       を指定する。
//    (3)ファイル(sv161b.dat)は、
//       c:/temp/sv161b.dat
//       に保存する。
//
///////////////////////////////////////////////////////////////////////////////

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class sv161b extends HttpServlet {

  // doGetメソッドやdoPostメソッドは要求ごとにスレッドとして実行される。
  // したがって、複数のスレッドでアクセスされる変数countに対して同時に実行され
  // ないように、synchronized指定をしておく必要がある。

  public void doPost(HttpServletRequest request, HttpServletResponse response)
                     throws ServletException,IOException {

    int count=0; // アクセス回数を記録する変数。


    for( int n=1; n<=3000; n++ ) {

      // synchronized指定。                             
      synchronized(this) {                              
        try {                                           
                                                        
          // 入力ストリームの作成。                        
          String fname = "c:/temp/sv161b.dat";          
          File f = new File(fname);                     
          if( f.exists() ) {                            
            FileReader fr = new FileReader(fname);      
            BufferedReader br = new BufferedReader(fr);      
            // 読込み。                                        
            String line = br.readLine();                     
            count = Integer.parseInt(line);             
            count++;                                    
            br.close();                                      
          } else {                                      
            count = 1;                                  
          }                                             
                                                        
          // 出力ストリームの作成。                     
          FileWriter fw = new FileWriter(fname);        
          PrintWriter out = new PrintWriter(fw);        
          out.println("" + count);                        
          out.close();                                  
        } catch( Exception e ) {                        
          System.out.println(e);                        
        }                                               
      }                                                 

    }


    // コンテンツタイプの指定。
    response.setContentType("text/html; charset=Shift_JIS");

    // HTML文書を送信。
    PrintWriter pw = response.getWriter();
    pw.println("<html>"                                    
        + "<head><title>サーブレット</title></head>"  
        + "<body>"
        + "<h2>アクセスカウンタ</h2>"
        + "<form action=http://localhost:8080/SV/servlet/sv161b method=POST>"
        + "<input type=submit value=登録>"
        + "</form>"
        + "現在の値: " + count + "<br>"            
        + "</body>"
        + "</html>");
    pw.flush();
    pw.close();    
  }
}
入力フォーム
<form action=http://localhost:8080/SV/servlet/sv161b method=POST>
  <input type=submit value=実行>
</form>
実行結果

一方のWebブラウザの実行をクリック後


他方のWebブラウザの実行をクリック後