Скажем, у меня есть класс TestServlet, который объявлен как глобальная строковая переменная. Если есть одновременные вызовы класса TestServlet, будет ли эта строковая переменная сообщения безопасна для печати без пересечения с параллельными потоками?

public class TestServlet extends HttpServlet {

  private String message;

  public void doGet(HttpServletRequest request,
                    HttpServletResponse response) throws ServletException, 
                                                         IOException {

      OutputStream os = response.getOutputStream();
      message = UUID.randomUUID().toString();
      os.write(message.getBytes());
  }


}
0
lannyboy 20 Апр 2014 в 05:58

2 ответа

Лучший ответ

Сервлет разделяется между запросами, поэтому нет, он не является потокобезопасным. Объект сервлета ограничен объявлением <servlet> в web.xml.

Контейнер создает экземпляр <servlet-class> для каждого сервлета и вызывает его метод init.

Некоторые ссылки здесь:

http://www.coderanch.com/t/473015/Servlets/java/Servlet-thread-safe

http://docs.oracle.com/javaee/5/tutorial/doc/bnafu.html

Как правило, если вы сохраняете состояние в сервлете, вам следует рассмотреть альтернативы. Зачем хранить там состояние? К чему привязано государство? Это привязано к запросу? Если да, используйте request.setAttribute. Если предполагается, что он будет использоваться одним и тем же пользователем по нескольким запросам, используйте request.getSession().setAttribute. Если он должен использоваться всеми запросами, то request.getServletContext().setAttribute.

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

public void doGet(HttpServletRequest request,
                  HttpServletResponse response) throws ServletException, 
                                                     IOException {

      OutputStream os = response.getOutputStream();
      String message = UUID.randomUUID().toString();
      os.write(message.getBytes());
  }

Обратите внимание, что здесь нет нелокальных переменных. Это довольно потокобезопасно.

3
Brandon 20 Апр 2014 в 02:11

Нет, сервлеты не являются потокобезопасными. Сервлеты не должны таким образом открывать какое-либо изменяемое состояние.

1
Tom G 20 Апр 2014 в 02:04