Факт: в жизни веб-приложения есть только 1 экземпляр сервлета. Он создается при запуске веб-приложения и уничтожается при завершении работы веб-приложения. Также см. этот ответ для грубой интерпретации.
Таким образом, он был разделен между всеми запросами (потоками). Если вы назначите данные области запроса или сеанса как переменную экземпляра (или, что еще хуже, как static
), то это определенно не будет потокобезопасным, поскольку затем оно будет разделено между всеми запросами (потоками) от всех пользователей (сеансов) всего приложения. Вам просто нужно назначить их как локальные переменные метода, чтобы сохранить их потокобезопасность. Итак:
public class MyServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
Это в основном все, что вам необходимо учитывать при разработке сервлетов с учетом безопасности потоков.
Кроме того, существуют атрибуты сеанса (HttpSession
), которые могут совместно использоваться несколькими запросами одного и того же пользователя, но в действительности вам не нужно беспокоиться о синхронизации доступа к сеансу. Обычно вы помещаете туда только данные пользователя, такие как вошедший в систему пользователь, предпочтения пользователя, корзину покупок и так далее. Вам просто нужно убедиться, что вы не помещаете чистые данные области запроса в область сеанса. Это будет отражено в нескольких окнах / вкладках браузера в одном сеансе.
Кроме того, существуют атрибуты приложения (ServletContext
), которые являются общими для всех пользователей приложения, но обычно вы помещаете туда только константы и другие статические данные, такие как конфигурация веб-приложения, фабрика DAO, содержимое выпадающего списка, и так далее. Кстати, все это можно сделать с помощью ServletContextListener
, также см. этот ответ для базового примера. Вам просто нужно убедиться, что вы не помещаете чистые данные области запроса или сеанса в область приложения.