2012-05-19 2 views
-3
HttpServletRequest request; 
    HttpServletResponse response; 

    public void doGet(HttpServletRequest request , HttpServlet response){ 
     this.request = request; 
     this.response = response; 
    } 

Что произойдет, если этот сервлет получает несколько запросов за раз?Почему apache сервлет Singleton?

Мы столкнулись с проблемой несоответствия ответа. Это проблема?

+8

Не делайте этого. В самом деле. Не. – skaffman

+1

Это заставляет мир погрузиться в черную дыру –

+0

Узнайте, как работают сервлеты: http://stackoverflow.com/questions/3106452/how-do-servlets-work-instantiation-session-variables-and-multithreading/3106909#3106909 – BalusC

ответ

-2

Его проблема и никогда не рекомендуется объявлять запрос HttpServletRequest/HttpServletResponse как переменную экземпляра. Фактически Servlet реализует модель одного потока, что означает, что создается только один экземпляр сервлета. И один поток для каждого запроса. Поэтому, если у них много запросов, то thr должно быть много потоков, и каждый из них будет использовать один экземпляр сервлета, который приведет к сбою данных или несогласованности данных. Темы будут работать в одних и тех же экземплярах.

+2

одиночная резьба модель! = Одиночный servlet. однопоточная модель - это точно модель (которую никто не использует, потому что она настолько неэффективна), что гарантирует, что только один поток использует данный сервлет. –

+0

Не рекомендуется также выполнять «однопоточную реализацию». Это устарело. – verisimilitude

+0

-1; этот ответ не дает никакой ценности. Как уже говорили другие, это частично неправильно. – home

2

Конечно, это проблема. Сервлет - синглтон. Тот же экземпляр сервлета используется для обработки всех запросов на этот сервлет. И запросы, конечно, обрабатываются одновременно. Это означает, что thread1 будет использовать запрос и ответ, обычно обрабатываемые thread2, если вы это сделаете.

+0

По определению, сервлеты не являются одиночными. API-интерфейс Servlet не ограничивает создание определенного класса Servlet для одного экземпляра. Контейнер обычно создает один экземпляр сервлета для каждого объявления сервлета в дескрипторе развертывания. В то время как синглтон представляет собой шаблон проектирования, который ограничивает создание объекта его класса равным 1 и только 1. – verisimilitude

+1

Они не являются одноточиями по смыслу шаблона GoF, но они эффектно связаны с тем, что контейнер ** необходим ** спецификацию сервлета, чтобы создать экземпляр только одного экземпляра для объявления сервлета. Синглтон - это не только шаблон дизайна GoF. Использовали ли вы когда-либо систему подбора зависимостей, например Spring или Guice? Никогда не видел, чтобы синглтон использовался в этом контексте? –

+0

Да, у меня есть. Я пытался сопоставить определение GoF с одним синглтоном.и плюс 1 для вашей разработки :) – verisimilitude

4

Ваш контейнер веб-приложений загружает только один экземпляр сервлета.

Чтобы написать потокобезопасные сервлеты, вы почти никогда не должны использовать переменные экземпляра вообще. Установка запроса и ответа в качестве переменных экземпляра просто неверна. Экземпляр сервлета не относится к одному запросу.

Если вам нужно сделать элементы запроса или ответа доступными для других методов, передайте их этим методам. Вы не нуждаетесь в них в качестве переменных экземпляра.

+1

Попробуйте написать нетривиальный сервлет без переменных экземпляра; сервлет должен делегировать управление * что-то * в какой-то момент (т. е. услуги). Вы хотите сказать, что нельзя использовать переменные экземпляров, не зависящие от потоков. – skaffman

0

Это определенно создаст проблему, любая переменная экземпляра будет совместно использоваться в качестве сервлета, так что одновременный запрос и объект ответа будут отменены.

1

Цитируя Servlet Спецификация

«Каждый запрос и ответ объекта действителен только в рамках метода обслуживания сервлета, или в пределах объема метода doFilter фильтр, в. Контейнеры обычно перерабатывают объекты запроса, чтобы избежать производительность накладных расходов создания объекта запроса . разработчик должен быть в курсе, что сохранение ссылки на запрос объектов за рамки описанного выше, не рекомендуется, поскольку это может иметь неопределенные результаты. "

+0

Это не имеет большого отношения к проблеме OP. Если он аннулирует переменные экземпляра в конце 'doGet()', область объектов запроса и ответа не будет распространяться вне метода службы, но у него все еще будут большие проблемы. –

+0

Правдоподобно. Но все равно. Если спецификация гарантирует неопределенные результаты при сохранении ссылок на эти объекты, почему это делать в конце концов? – verisimilitude

+0

Это не гарантирует ничего подобного. Вы можете сохранить столько ссылок, сколько захотите, так долго вы не будете использовать эти ссылки вне сферы действия метода службы. Вам просто нужно сделать это поточно-безопасным способом. Например, многие фреймворки хранят ссылку на запрос в переменной ThreadLocal. –

0

что происходит, что ваш сервлет Instan tly становится не реентерабельным и, конечно же, не сможет выполнить первый раз, когда он будет вызван более чем одним клиентом одновременно. Вы не должны этого делать.

Смежные вопросы