Servlet 2.5 spec:
Multiple servlets executing request
threads may have active access to the
same session object at the same time.
The container must ensure that
manipulation of internal data
structures representing the session
attributes is performed in a
threadsafe manner. The Developer has
the responsibility for threadsafe
access to the attribute objects
themselves. This will protect the
attribute collection inside the
HttpSession object from concurrent
access, eliminating the opportunity
for an application to cause that
collection to become corrupted.
This is safe:
// guaranteed by the spec to be safe
request.getSession().setAttribute("foo", 1);
This is not safe:
HttpSession session = request.getSession();
Integer n = (Integer) session.getAttribute("foo");
// not thread safe
// another thread might be have got stale value between get and set
session.setAttribute("foo", (n == null) ? 1 : n + 1);
This is not guaranteed to be safe:
// no guarantee that same instance will be returned,
// nor that session will lock on "this"
HttpSession session = request.getSession();
synchronized (session) {
Integer n = (Integer) session.getAttribute("foo");
session.setAttribute("foo", (n == null) ? 1 : n + 1);
}
I have seen this last approach advocated (including in J2EE books), but it is not guaranteed to work by the Servlet specification. You could use the session ID to create a mutex, but there must be a better approach.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…