说,我有一个TestServlet类,它声明为全局字符串变量。如果同时调用TestServlet类,这个'message'字符串变量是否可以安全打印而不会从并发线程中穿过?
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 :(得分:3)
servlet在请求之间共享,所以不,它不是线程安全的。 servlet对象的范围限定为web.xml中的<servlet>
声明。
容器为每个servlet创建<servlet-class>
的实例,并调用其init
方法。
这里有一些参考:
http://www.coderanch.com/t/473015/Servlets/java/Servlet-thread-safe
http://docs.oracle.com/javaee/5/tutorial/doc/bnafu.html
通常,如果要在servlet中存储状态,则应考虑替代方法。为什么要存储状态?国家关系到什么?它与请求有关吗?如果是,请使用request.setAttribute
。如果要由同一用户在多个请求之间共享,请使用request.getSession().setAttribute
。如果它应由所有请求共享,则为request.getServletContext().setAttribute
。
如果状态特定于单个请求,并且仅在执行此servlet时,那么它应该只是方法中的局部变量。例如:
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
OutputStream os = response.getOutputStream();
String message = UUID.randomUUID().toString();
os.write(message.getBytes());
}
注意这里没有非局部变量。这是相当线程安全的。
答案 1 :(得分:1)
不,servlet不是线程安全的。 Servlet不应以这种方式暴露任何类型的可变状态。