Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2534280
  • 博文数量: 245
  • 博客积分: 4125
  • 博客等级: 上校
  • 技术积分: 3113
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-25 23:56
文章分类

全部博文(245)

文章存档

2015年(2)

2014年(26)

2013年(41)

2012年(40)

2011年(134)

2010年(2)

分类: Java

2014-06-15 10:41:27

每个servlet只有一个实例,怎样保证servlet是线程安全(thread-safe)的?

servlet容器启动过程:

1.reads web.xml;
2.finds the declared Servlets in the classpath; and
3. loads and instantiates each Servlet only once.
对该过程的代码描述:

String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // Similar to a map interface.

Those Servlets are stored in memory and reused every time the request URL matches the Servlet’s associated url-pattern. The servlet container then executes code similar to:

for (Entry entry : servlets.entrySet()) {
    String urlPattern = entry.getKey();
    HttpServlet servlet = entry.getValue();
    if (request.getRequestURL().matches(urlPattern)) {
        servlet.service(request, response);
        break;
    }
}

The GenericServlet#service() on its turn decides which of the doGet(), doPost(), etc.. to invoke based on HttpServletRequest#getMethod().

You see, the servletcontainer reuses the same servlet instance for every request. In other words: the servlets are shared among every request. That’s why it’s extremely important to write servlet code the threadsafe manner –which is actually simple: just do not assign request or session scoped data as servlet instance variables, but just as method local variables. E.g.

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.
    } 
}

there is only one instance of the servlet which is reused for multiple requests from multiple clients. This leads to two important rules:
don’t use instance variables in a servlet, except for application-wide values, most often obtained from context parameters.
don’t make methods synchronized in a servlet
According to the Java Servlet Specification Version 3.0 (pp. 6-7), there will be one instance per declaration per JVM, unless the servlet implements SingleThreadModel in which case there may be multiple instances per JVM.

阅读(3413) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~