0

これは、私の以前の投稿に関連する姉妹の質問です: 高同時実行性が満たされる場合の単純な Web サーバー

インタビューの質問は次のとおりです。

public class CounterServlet extends HttpServlet{

 private volatile static int counter=0;

 public int getCounter()
 {
   return counter;
 }

 public void service(HttpServletRequest request
                     HttpServletResponse response) throws IOException
 {
    counter++;
    PrintWriter out=response.getWriter();
    out.write("hello");
 }

高い同時実行性が発生した場合、上記のコードでどのような問題が発生しますか? 私の分析は次のとおりです。サーブレットはシングルトンであるため、同期に問題が発生します。カウンターが揮発性として宣言されているため、問題を防ぐことはできません。サービスメソッドを同期することをお勧めしますか?

4

3 に答える 3

1

volatile はコンパイラにこの変数を最適化しないように指示しているだけなので、同時実行性に関連する問題には役立ちません。

counterインクリメントするだけなので、何をしようとしているのかわかりませんが、serviceメソッドを N 回呼び出した後、カウンターが N に等しくならないことは確かです。

それを防ぐには、メソッドを同期させるか (これは正しいアプローチではないと思います)、ロック オブジェクトのインクリメント部分を同期するか、(これが最も適切な方法だと思います) int の代わりに AtomicInteger - AtomicInteger を使用します。クラスは、オブジェクトに対するすべての操作がアトミックに行われることを保証します。

于 2013-05-15T08:42:15.460 に答える
1

その目的にはAtomicIntegerを使用する必要があります。ただし、複数のクライアントからの複数のリクエストに再利用されるサーブレットのインスタンスは 1 つしか存在しないため、サーブレットでインスタンスまたはクラス変数を宣言したり、メソッドを同期させたりしないでください。プリミティブを使用する場合は、以下のようにしますint

public void service(HttpServletRequest request
                 HttpServletResponse response) throws IOException
{
   synchronized (CounterServlet.class) {
        count++;
    }      
   PrintWriter out=response.getWriter();
   out.write("hello");
}
于 2013-05-15T08:43:55.723 に答える