在下面的代码中如果我不使用synchronized(this)会发生什么?这个servlet是否正确覆盖了servlet规则?
Integer counter = new Integer(0);// instance variable
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
try {
out.println("<html><head><title>Calculate Number of Times Visits Using Session</title></head><body>");
HttpSession visitSession = request.getSession(true);
if(visitSession.isNew())
out.println("This is the first time you are visiting this page.");
else
out.println("Welcome back to this page");
synchronized(this) {
out.println("<br><br>You have visited this page " + (++Counter));
out.println((Counter == 1) ? " time " : " times ");
}
out.println("</body></html>");
} finally {
out.close();
}
}
答案 0 :(得分:1)
这取决于什么是反击。
如果counter是servlet的实例变量,那么必须使用synchronized beacause多个线程(服务器的池线程)可以访问相同的变量(“Counter”)进行读写。
在这种情况下,如果你没有同步块,可以打印计数器丢失一些数字(例如执行两次“++”操作,然后两次读取,所以你失去阅读un“++”操作)。
如果使用同步,则输出始终为
You have visited this page 1 time
You have visited this page 2 times
You have visited this page 3 times
等等。
如果您不使用同步,则输出可以是任何顺序,例如
You have visited this page 1 time
You have visited this page 3 times
You have visited this page 3 times
You have visited this page 4 times
You have visited this page 6 times
You have visited this page 6 times
答案 1 :(得分:0)
因为计数器(变量)是全局声明的,所以它不是线程安全的,为了使其线程安全,请在goGet()中声明它,在这种情况下,synchronized是不必要的。