【问题标题】:Cleanest way to initialize a session variable in a servlet在 servlet 中初始化会话变量的最简洁方法
【发布时间】:2017-04-25 23:58:17
【问题描述】:

考虑到会话变量本质上不是线程安全的,什么是在 servlet 中初始化会话变量的干净利落的方法?

考虑以下代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    // NOT thread safe
    if( request.getSession().getAttribute("mySessionVariable") == null )
        request.getSession().setAttribute("mySessionVariable", new AtomicInteger(0));

    ((AtomicInteger) request.getSession().getAttribute("mySessionVariable")).incrementAndGet();

}

在上面的代码中,有可能两个线程会同时看到变量为空,因此都将其初始化为 0。为了避免这种情况,当然可以使用同步块:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    synchronized(this){
        if( request.getSession().getAttribute("mySessionVariable") == null )
            request.getSession().setAttribute("mySessionVariable", new AtomicInteger(0));

        ((AtomicInteger) request.getSession().getAttribute("mySessionVariable")).incrementAndGet();
    }

}

但我想知道,有没有更清洁和“更漂亮”的方法来实现同样的目标?

【问题讨论】:

    标签: java multithreading session servlets


    【解决方案1】:

    创建用户会话时,可以在会话中添加mySessionVariable属性:

     session.setAttribute("mySessionVariable", new AtomicInteger(0));
    

    如果您没有在 servlet 中显式处理 Session 的创建,您可以在 public void sessionCreated(HttpSessionEvent arg0) 方法中使用 HttpSessionListener 进行初始化。

    因此,此代码变得线程安全,因为您不再需要初始化属性并且AtomicInteger 自动设置int 值:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException{ 
    
       ((AtomicInteger)request.getSession().getAttribute("mySessionVariable")).incrementAndGet();
    
    }
    

    【讨论】:

    • 这是一个很好的建议,但由于某种原因我无法实现 - 请参阅我的 other question
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-14
    • 1970-01-01
    • 2015-04-08
    相关资源
    最近更新 更多