スレッドセーフではないコード(1回目)

書いてはいけないコードの例。アクセスカウント(requestCount)を表示するサーブレットを考える。

サーブレット自体はシングルトンなので、ブラウザからアクセスするとrequestCountの値がインクリメントされ、正しく動くかのように見える。

しかし、++のインクリメントはアトミックな操作ではないので、正しくインクリメントされた値がブラウザに表示される保証は無い。これを「競り合い状態(race condition)」と言う*1

仕様は理解できるが、実際に期待通り動作しない状況を再現するにはどうすれば良いものやら・・・次回を参考にして下さい。

package test;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CounterServlet extends HttpServlet {

	int requestCount = 0;

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
		PrintWriter writer = response.getWriter();
		writer.print(++requestCount);
		writer.close();
	}
}

サーブレットの仕様に関する参考
http://stackoverflow.com/questions/10665223/why-apache-servlet-is-singleton

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―

Java並行処理プログラミング ―その「基盤」と「最新API」を究める―

*1:Java並行処理プログラミングのp6〜p9参照