UPDATE: Solution right after question.
Question:
Usually, synchronization is serializing parallel requests within a JVM, e.g.
private static final Object LOCK = new Object();
public void doSomething() {
...
synchronized(LOCK) {
...
}
...
}
When looking at web applications, some synchronization on "JVM global" scope is maybe becoming a performance bottleneck and synchronization only within the scope of the user's HttpSession would make more sense.
Is the following code a possibility? I doubt that synchronizing on the session object is a good idea but it would be interesting to hear your thoughts.
HttpSession session = getHttpServletRequest().getSession();
synchronized (session) {
...
}
Key Question:
Is it guaranteed that the session object is the same instance for all threads processing requests from the same user?
Summarized answer / solution:
It seems that the session object itself is not always the same as it depends on the implementation of the servlet container (Tomcat, Glassfish, ...) and the getSession()
method might return just a wrapper instance.
So it is recommended to use a custom variable stored in the session to be used as locking object.
Here is my code proposal, feedback is welcome:
somewhere in a Helper Class, e.g. MyHelper
:
private static final Object LOCK = new Object();
public static Object getSessionLock(HttpServletRequest request, String lockName) {
if (lockName == null) lockName = "SESSION_LOCK";
Object result = request.getSession().getAttribute(lockName);
if (result == null) {
// only if there is no session-lock object in the session we apply the global lock
synchronized (LOCK) {
// as it can be that another thread has updated the session-lock object in the meantime, we have to read it again from the session and create it only if it is not there yet!
result = request.getSession().getAttribute(lockName);
if (result == null) {
result = new Object();
request.getSession().setAttribute(lockName, result);
}
}
}
return result;
}
and then you can use it:
Object sessionLock = MyHelper.getSessionLock(getRequest(), null);
synchronized (sessionLock) {
...
}
Any comments on this solution?
HttpSession
synchronization/locking, not whetherHttpSession
is thread-safe or not. – Jackysynchronized
will not work if you use a cluster with session replication and when several requests for the same session are handled by different servers. – Foam