HttpSessionAttributeListener是否已处理异步?

时间:2015-10-22 06:52:18

标签: java session servlets listener

考虑算法:

  1. 将新属性添加到会话session.setAttribute("myObject", new Object);
  2. HttpSessionAttributeListener#attributeAdded已被调用
  3. session.setAttribute
  4. 之后的代码

    HttpSessionAttributeListener#attributeAdded阻止session.setAttribute或侦听器代码是否会调用异步?

2 个答案:

答案 0 :(得分:3)

在调用set|get|removeAttribute()的同一个线程中调用侦听器。

因此,在另一个线程中调用setAttribute()时,可能会出现唯一的竞争条件。假设平均servlet容器使用single thread per HTTP connection(因此当HTTP 1.1 keep-alive打开时不一定每HTTP请求),那么当最终用户产生两个完全独立的浏览器实例时,可能会出现这种竞争情况(不是windows / tabs)并将会话cookie从一个复制到另一个,然后在该会话中同时触发两个客户端的请求,触发服务器中的setAttribute()方法。

然而,这不是通常的现实案例。而且,容器本身都会担心访问HttpSession实例的线程安全性。这在Servlet specification(强调我的)的第7.7.1章中有详细说明:

  

7.7.1线程问题

     

执行请求线程的多个servlet可以具有对它的活动访问权限   会话对象同时出现。 容器必须确保操纵   表示会话属性的内部数据结构在线程中执行   安全的方式。开发人员负责线程安全访问   属性对象本身。这将保护内部的属性集合   来自并发访问的HttpSession对象,消除了一个机会   应用程序导致该集合损坏。

所以你唯一关心的是属性本身的安全性。例如。如果它是ArrayList,并且您担心其线程安全,那么您可能希望将其包装在Collections#synchronizedList()中。

答案 1 :(得分:1)

它是一个SYNC过程。我刚做了一个示例程序。

JSP代码:

<%
session.setAttribute("ID","12324");
session.setAttribute("ID2","656565");
%>

listener CodeAdded of AttributeAdded()方法:

String attributeName = event.getName();
        Object attributeValue = event.getValue();
        System.out.println("Attribute added : " + attributeName + " : " + attributeValue);
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("After Sleep : "+attributeName);
  

输出:

Attribute added : ID : 12324
After Sleep : ID
Attribute added : ID2 : 656565
After Sleep : ID2

所以你可以看到,只有在第一个id打印“After Sleep”后才能在会话中添加第二个id