在Java中,如何确保我的web应用程序是线程安全的?
如何确保java servlets web应用程序是线程安全的?对于会话变量、类的静态变量或任何其他可能是线程安全问题的变量,我需要做些什么?您的意思是在上下文中而不是在任何其他java应用程序中?其实差别不大。对servlet的每个请求都会导致容器发出一个新线程来处理它,因此servlet中的实例变量必须是线程安全的。最好在doGet/doPost()方法中使用局部变量处理所有业务。我能想到一个办法。对于会话变量,可能是用户打开了两个浏览器窗口,都指向您的应用程序。在这种情况下,还需要注意会话范围的线程安全 哇,这是一个很难回答的问题 简单地说,您需要确保对任何共享数据的访问都是仔细同步的。例如,您可能希望使用互斥锁或同步函数同步对静态变量的访问 请注意,如果需要同时修改多个共享资源的原子事务,则可能还需要在更高级别进行同步 设计一个并发应用程序并不简单,而且没有灵丹妙药(不幸的是)。关于编写安全并发代码的更多信息,我强烈推荐本书。在Java中,如何确保我的web应用程序是线程安全的?,java,servlets,jakarta-ee,Java,Servlets,Jakarta Ee,如何确保java servlets web应用程序是线程安全的?对于会话变量、类的静态变量或任何其他可能是线程安全问题的变量,我需要做些什么?您的意思是在上下文中而不是在任何其他java应用程序中?其实差别不大。对servlet的每个请求都会导致容器发出一个新线程来处理它,因此servlet中的实例变量必须是线程安全的。最好在doGet/doPost()方法中使用局部变量处理所有业务。我能想到一个办法。对于会话变量,可能是用户打开了两个浏览器窗口,都指向您的应用程序。在这种情况下,还需要注意会话
- 不要使用servlet和过滤器的实例变量
- 不要使用静态变量
- 思考
static
)变量,那么它肯定不是线程安全的,因为它随后在应用程序范围内来自所有用户(会话)的所有请求(线程)之间共享。您只需要将它们指定为方法局部变量,以保持线程安全。因此:
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时需要考虑的全部内容
还有session()属性,可以在来自同一用户的多个请求之间共享,但在现实世界中,您实际上不需要担心同步会话访问。您通常只将特定于用户的数据放在那里,例如登录用户、特定于用户的首选项、购物篮等。您只需要确保不会将纯请求范围的数据放入会话范围。它将反映在同一会话中的多个浏览器窗口/选项卡中
还有application()属性,这些属性在应用程序范围内的所有用户之间共享,但通常只在其中放置常量和其他静态数据,如webapp配置、DAO工厂、dropdownlist内容等。顺便说一句,这一切都可以用a来完成,另请参见一个基本示例。您只需确保不会将纯请求范围或会话范围的数据放入应用程序范围。我认为第4项几乎取代了(涵盖)1-3.:)好吧,在你能好好思考一个关于“web应用生命周期中的一个servlet”的问题之前,需要一些基本知识——我认为这是一个池对象,所以servlet引擎可以根据负载的不同决定不止一个。这不是真的吗?除非它实现了(根据Servlet 2.4弃用)
SingleThreadModel
@BalusC:非常感谢,先生,这个答案最终帮助了我。我删除了我的问题,并对你的答案投了赞成票。在Java中没有人能像你一样。再次感谢你。