Ссылаясь на статью Брайана Гетца Разве все веб-приложения с сохранением состояния нарушены? для IBM developerWorks, я хочу сослаться на этот фрагмент кода
HttpSession session = request.getSession(true);
ShoppingCart cart = (ShoppingCart)session.getAttribute("shoppingCart");
if (cart == null) {
cart = new ShoppingCart(...);
session.setAttribute("shoppingCart", cart);
}
doSomethingWith(cart);
Из моего доступного понимания этот код не является потокобезопасным, поскольку использует шаблон check-then-act. Но у меня есть сомнения:
Не является ли создание или извлечение HttpSession
в первой строке полностью атомным? По атомарному я имею в виду, что если два потока вызывают request.getSession()
, один будет блокироваться. Хотя оба будут возвращать один и тот же экземпляр HttpSession
. Таким образом, если клиент (мобильные/веб-браузеры) делает два или совершает вызовы на тот же сервлет (который выполняет вышеприведенный фрагмент), вы никогда не получите ситуацию, в которой разные потоки видят разные значения для cart
.
Предполагая, что я убежден, что это НЕ потокобезопасность, как можно сделать этот поток безопасным? Будет ли работать AtomicReference
? например:.
HttpSession session = request.getSession(true);
AtomicReference<ShoppingCart> cartRef =
(<AtomicReference<ShoppingCart>)session.getAttribute("shoppingCart");
ShoppingCart cart = cartRef.get();
if (cart == null) {
cart = new ShoppingCart(...);
session.setAttribute("shoppingCart",
new AtomicReference<ShoppingCart>(cart));
}
doSomethingWith(cart);
Merci!