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.