问题描述
如何确保我的 java servlet 网络应用程序是线程安全的?对于会话变量、类的静态变量或其他任何可能是线程安全问题的东西,我需要做什么?
How do I make sure my java servlets web application is thread safe? What do I need to do in regards to session variables, static variables of a class, or anything else that could be a thread-safety problem?
推荐答案
事实:在 webapp 的生命周期中只有 1 个 servlet 实例.它在 webapp 启动时创建,并在 webapp 关闭时销毁.另见 这个答案 粗略的解释.
Fact: there's only 1 instance of a servlet in webapp's lifetime. It get created on webapp's startup and it get destroyed on webapp's shutdown. Also see this answer for a rough interpretation.
因此,它在所有请求(线程)之间共享.如果您将请求或会话范围的数据分配为实例(或者更糟的是,作为 static
)变量,那么它绝对不是线程安全的,因为它会在来自所有用户(会话)的所有请求(线程)之间共享) 应用广泛.您只需要将它们分配为方法局部变量即可使它们保持线程安全.所以:
Thus, it's been shared among all requests (threads). If you assign request or session scoped data as instance (or even worse, as static
) variable, then it is definitely not threadsafe, because it's then been shared among all requests (threads) from all users (sessions) applicationwide. You just need to assign them as method local variables to keep them threadsafe. So:
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.
}
}
在开发具有线程安全性的 servlet 时,这基本上就是您需要考虑的全部内容.
That's basically all you need to take into account when developing servlets with threadsafety in mind.
然后是会话(HttpSession
) 属性可以在来自同一用户的多个请求之间共享,但在现实世界中,您实际上不需要担心同步会话访问.您通常只在那里放置特定于用户的数据,例如登录用户、特定于用户的偏好、购物篮等.您只需要确保不要将纯请求范围的数据放入会话范围内.它会反映在同一会话内的多个浏览器窗口/选项卡中.
Then there are session (HttpSession
) attributes which can be shared among multiple requests from the same user, but in real world you actually don't need to worry about synchronizing session access. You normally put only user-specific data there, such as the logged-in user, user-specific preferences, the shopping basket, etcetera. You just need to ensure that you don't put pure request scoped data in the session scope. It would get reflected in multiple browser windows/tabs inside the same session.
然后是应用程序(ServletContext
) 在应用程序范围内的所有用户之间共享的属性,但您通常只将常量和其他静态数据放在那里,例如 webapp 配置、DAO 工厂、下拉列表内容等.这一切都可以通过 ServletContextListener
,另见这个答案以获得基本的例子.您只需要确保不会将纯请求范围或会话范围的数据放入应用程序范围.
Then there are application (ServletContext
) attributes which are shared among all users applicationwide, but you normally put only constants and other static data there, like the webapp configuration, DAO factory, dropdownlist contents, etcetera. This all can by the way be done with a ServletContextListener
, also see this answer for a basic example. You just need to ensure that you don't put pure request- or session scoped data in the application scope.
这篇关于在 Java 中,如何确保我的 Web 应用程序是线程安全的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!