Почему сервлеты не безопасны?

Мне нужно знать, почему сервлеты не являются потокобезопасными? И в чем причина того, что в сервлетах контроллера Struts 2.0 фреймворк является потокобезопасным?

6 ответов

Решение

Мне нужно знать, почему сервлеты не являются потокобезопасными?

Экземпляры сервлета по своей природе не являются поточно-ориентированными из-за многопоточной природы языка программирования Java в целом. Виртуальная машина Java поддерживает выполнение одного и того же кода несколькими потоками. Это большое преимущество в производительности на машинах с несколькими процессорами. Это также позволяет одному и тому же коду выполняться несколькими одновременными пользователями, не блокируя друг друга.

Представьте себе сервер с 4 процессорами, в котором обычный сервлет может обрабатывать 1000 запросов в секунду. Если бы этот сервлет был потокобезопасным, то веб-приложение работало бы так, как если бы оно работало на сервере с 1 процессором, где сервлет может обрабатывать только 250 запросов в секунду (хорошо, это не совсем так, но у вас есть идея).

Если вы сталкиваетесь с проблемами безопасности потоков при использовании сервлетов, то это ваша ошибка, а не ошибка Java или Servlet. Вам необходимо исправить код сервлета так, чтобы данные области запроса или сеанса никогда не назначались в качестве переменной экземпляра сервлета. Подробное объяснение см. Также Как работают сервлеты? Создание экземпляров, сессий, общих переменных и многопоточности.

И в чем причина того, что в сервлетах контроллера Struts 2.0 фреймворк является потокобезопасным?

Это не потокобезопасно. Вы путаете фильтр сервлетов диспетчера Struts с действиями Struts. Действия Struts воссоздаются при каждом запросе. Таким образом, у каждого отдельного запроса есть свой экземпляр действия Struts. Фильтр сервлетов диспетчера Struts не сохраняет их как свою собственную переменную экземпляра. Вместо этого он хранит его как атрибут HttpServletRequest,

Сервлеты - это обычные Java-классы, поэтому они НЕ являются поточно-ориентированными

Тем не менее, классы Java безопасны для потоков, если у вас нет переменных экземпляра. Синхронизировать нужно только переменные экземпляра. (Переменные экземпляра - это переменные, объявленные в классе, а не в его методах.

Переменные, объявленные в методах, являются потокобезопасными, так как каждый поток создает свой собственный программный стек, а переменные функции размещаются в стеке. Это означает, что переменные в методах создаются для каждого потока, следовательно, с ними не связано никаких проблем синхронизации потока.

Переменные метода являются поточно-ориентированными, а переменные класса - нет.

Существует один экземпляр сервлета на отображение сервлета; все свойства экземпляра распределяются между всеми запросами. Доступ к этим свойствам должен учитывать это.

Действия Struts 2 (не "сервлет контроллера", они не являются ни сервлетами, ни контроллерами) создаются для каждого запроса. Свойства действия будут доступны только потоку одного запроса.

Сервлеты обычно многопоточные.

Контейнеры сервлетов обычно управляют параллельными запросами, создавая новый поток Java для каждого запроса. Новый поток получает объектную ссылку на запрошенный сервлет, который выдает ответ через тот же поток. Вот почему важно создавать параллелизм при написании сервлета, поскольку один и тот же экземпляр сервлета может обрабатывать несколько запросов.

Способ, которым контейнеры сервлета обрабатывают запросы сервлета, зависит от реализации; они могут использовать один сервлет, они могут использовать пул сервлетов, это зависит от архитектуры системы поставщика.

Struts 2 Объекты Action создаются для каждого запроса, поэтому проблем с безопасностью потоков нет.

Сервлет не является потокобезопасным, но мы можем сделать его потокобезопасным, реализовав этот класс сервлетов для SingleThreadModelкак приведенное ниже определение класса, но опять-таки проблема с производительностью будет, поэтому лучшим вариантом будет использование синхронизированной части

public class SurveyServlet extends HttpServlet
                           implements SingleThreadModel
{
servlet code here..
...
}

Сервлет сам по себе не является потокобезопасным. Вы можете сделать его поточно-ориентированным, синхронизировав метод обслуживания. вам нужно реализовать SingleThreadInterface, чтобы сделать его потокобезопасным.

Другие вопросы по тегам