Servlet并发
时间:2020-01-09 10:36:22 来源:igfitidea点击:
Java Servlet容器/ Web服务器通常是多线程的。这意味着,可以同时执行对同一servlet的多个请求。因此,在实现servlet时需要考虑并发性。
我不会在这里详细描述Java并发。如果我们对此主题感兴趣,请阅读我的Java Concurrency教程。
为了确保Servlet是线程安全的,必须遵循一些基本经验法则:
- 除非这些成员变量本身是线程安全的,否则servlet service()方法不应访问任何成员变量。
- servlet service()不应重新分配成员变量,因为这可能会影响在service()方法内执行的其他线程。如果确实需要重新分配成员变量,请确保在同步块内完成此操作。
- 规则1和2也计入静态变量。
- 局部变量始终是线程安全的。但是请记住,局部变量指向的对象可能并非如此。如果对象是在方法内部实例化的,并且从未转义,则不会有问题。另一方面,指向某些共享库的局部变量可能仍然会引起问题。仅仅因为我们将共享对象分配给本地引用,并不意味着该对象自动成为线程安全的。
当然,请求和响应对象是线程安全使用的。为servlet中的每个请求创建一个新的实例,从而为servlet中执行的每个线程创建一个实例。
其他共享资源
当然,不仅需要注意Servlet类本身内部的成员变量和静态变量,还需要注意访问。 servlet访问的任何其他类中的静态变量也必须是线程安全的。对于servlet访问的所有shread对象的成员变量,也是如此。
程式码范例
这是一个代码示例,向我们显示我在本文中一直在谈论的一些规则。
public class SimpleHttpServlet extends HttpServlet { // Not thread safe, static. protected static List list = new ArrayList(); // Not thread safe protected Map map = new HashMap(); // Thread safe to access object, not thread safe to reassign variable. protected Map map = new ConcurrentHashMap(); // Thread safe to access object (immutable), not thread safe to reassign variable. protected String aString = "a string value"; protected void doGet( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Not thread safe, unless the singleton is 100% thread safe. SomeClass.getSomeStaticSingleton(); // Thread safe, locally instantiated, and never escapes method. Set set = new HashSet(); } }