首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高并发发生时的Servlet问题

高并发发生时的Servlet问题
EN

Stack Overflow用户
提问于 2013-05-15 16:34:52
回答 3查看 977关注 0票数 0

这是一个与我之前的帖子相关的姐妹问题:Simple web server when high-concurrency is met

面试问题是:

代码语言:javascript
复制
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");
 }

当遇到高并发时,上面的代码会有什么问题?我的分析是:Servlet是单例的,因此在synchronization.It中会有问题,将计数器声明为易失性,这不会阻止该问题。我建议同步服务方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-05-15 16:48:15

如果你通过多个线程访问一个静态值,那么每个线程都可以拥有它的本地缓存副本!为了避免这种情况,您可以将变量声明为static volatile,这将强制线程每次读取全局值。然而,易失性并不能代替正确的同步!

您需要同步代码,尽管您只是在计数器上进行递增,但这并不意味着整个方法将是原子的。可能有多个线程使用来自寄存器的当前值同时递增它。这可能会导致不期望的结果。

对于这种微不足道的操作,您需要对该方法执行synchronize操作或使用AtomicInteger

票数 2
EN

Stack Overflow用户

发布于 2013-05-15 16:42:15

因为volatile只是告诉编译器不要优化这个变量,所以它不会帮助解决与并发相关的问题。

我不知道您将如何处理counter,因为您只会递增它,但我们可以肯定,在N次调用service方法之后,计数器将不会等于N。

为了防止这种情况的发生,可以使方法同步(我认为这不是正确的方法),同步某个锁对象上的递增部分,或者(我认为这是最合适的方法)使用AtomicInteger而不是int - AtomicInteger类来确保对象上的所有操作都是自动完成的。

票数 1
EN

Stack Overflow用户

发布于 2013-05-15 16:43:56

您应该对该purpose.But使用AtomicInteger,因为该Servlet只存在一个实例,可供来自多个clients.Hence的多个请求重用。如果您想使用原语int,请不要在Servlet中声明任何实例或类变量,也不要使方法synchronized.You可以做如下所示的事情。

代码语言:javascript
复制
public void service(HttpServletRequest request
                 HttpServletResponse response) throws IOException
{
   synchronized (CounterServlet.class) {
        count++;
    }      
   PrintWriter out=response.getWriter();
   out.write("hello");
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16560339

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档