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();

  }
}