Servlet/JSP 応用編01 マルチスレッド

はじめに

僕たちの使うWebサイトは、複数人のユーザが同時に使用することが普通である。そのため、起動されたサーブレットインスタンスは、同時に複数のユーザに利用される可能性が高い。そこで、サーブレットはマルチスレッドを使い、複数のユーザに対するリクエストを、平行に処理する。

問題点

マルチスレッドで動作することを考慮したマルチスレッドプログラミングでは問題点があり、それは、ある特定の変数を複数のスレッドが同時に操作する可能性があるということである。
例としては、一つのカウンタを、二人のユーザが同時に操作する場合がある。ユーザA、ユーザBがおり、お互いがカウンタの値を1ずつ増やす処理の時、Aが足して、更新をする前に、Bがカウンタを扱ってしまうと、値が変わらないままになってしまう。つまり、必ず、更新を行ったあとにお互いがカウンタに干渉するべきである。工夫として、待ち時間を置くという方法がある。

作成するプログラム

実際に時間をおいて処理をするというプログラムを書いてみた。

public class CountThread extends HttpServlet{
    int count;

    public void doGet(HttpServletRequest request ,HttpServletResponse response)
    throws ServletException , IOException{
        PrintWriter out = response.getWriter();
        Page.header(out);

        int i = count;
        try{
            Thread.sleep(3000);
        } catch(InterruptedException e){}

        count=i+1;
        out.println(count);

        Page.footer(out);
    }

 まず、変数iに変数countを代入する。次に、try文の中で、sleepメソッドで3秒間、時間を空けて、変数countに1 増やす。

一つ、気になるのが、なぜ、「count」と「i」で値を分けているのかという点だろうが、これは、グローバル変数か、クラス変数かの違いである。クラス変数はスレッド間で共有されるが、グローバル変数は、スレッドごとに用意される。なので、ローカル変数だけ操作するときは、同時操作の問題を考えなくてよい。

ブラウザでの結果を見てみる。

f:id:kouki-matsuura:20200907104136p:plain

一度目は、「1」と表示されており、更新すると、数が増えていることが確認できる。

f:id:kouki-matsuura:20200907104156p:plain

おわりに

今回は、マルチスレッドについてとても簡単に解説した。他にも、マルチスレッドを扱う際には、「synchronizedブロック」という方法もある。
次回は、HTTPのリクエストについて、解説していきたいと思う。