ОБНОВЛЕНИЕ: Решение сразу после вопроса.Возможно ли синхронизация внутри HttpSession?
Вопрос:
Обычно синхронизация сериализации параллельных запросов в пределах виртуальной машины Java, например
private static final Object LOCK = new Object();
public void doSomething() {
...
synchronized(LOCK) {
...
}
...
}
При просмотре веб-приложений, некоторые синхронизации на «JVM глобальной» Прицел может быть, становится узким местом производительности и синхронизации только в пределах HttpSession бы больше смысла пользователя.
Возможно ли использовать следующий код? Я сомневаюсь, что синхронизация на объекте сеанса - хорошая идея, но было бы интересно услышать ваши мысли.
HttpSession session = getHttpServletRequest().getSession();
synchronized (session) {
...
}
Ключевой вопрос:
ли он гарантировал, что объект сеанса тот же экземпляр для всех потоков обработки запросов от одного пользователя?
Обобщенный ответ/решение:
Кажется, что сам объект сеанса не всегда такой же, как в зависимости от реализации контейнера сервлетов (Tomcat, GlassFish, ...) и метод getSession()
может возвращать только экземпляр обертки.
Поэтому рекомендуется использовать пользовательскую переменную, хранящуюся в сеансе, которая будет использоваться в качестве объекта блокировки.
Вот мой код предложения, обратная связь приветствуется:
где-то в классе Helper, например, 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;
}
, а затем вы можете использовать его:
Object sessionLock = MyHelper.getSessionLock(getRequest(), null);
synchronized (sessionLock) {
...
}
Любые комментарии по этому решению?
Возможный дубликат [Является ли потоком HttpSession безопасным, установлены/получают атрибуты потока атрибутов потока?] (Http://stackoverflow.com/questions/616601/is-httpsession-thread-safe-are-set-get-attribute -thread-safe-operations) –
Это не дубликат, поскольку связанный вопрос касается безопасности потоков переменных сеанса. Я спрашиваю, можете ли вы заблокировать сам объект сеанса. – basZero
@SahilMuthoo: Я не согласен, OP спрашивает, какой объект безопасен для синхронизации/блокировки HttpSession, а не является ли HttpSession «потокобезопасным» или нет. –