每个 tomcat 服务器只有一个 servlet 对象吗?

Is there only one servlet object per tomcat server?

我做了一个简单的测试,并从不同的浏览器和命令行工具执行了下面的测试 servlet。无论我在哪里执行它,它都显示相同的 "hohoho time"。我对此非常满意,我只想知道两件事:

a) 如果我可以在不同版本的 tomcat 上依赖它(今天我使用 7.54 版)

b) 这是否意味着 servlet 永远不会在不同线程中并行执行(即两个用户同时请求同一个 servlet)

@WebServlet(name="test servlet 2", urlPatterns={"/test2"}, loadOnStartup=1)
public class Test2 extends HttpServlet {
    private String test = "baaa .. :-(";

    @Override
    public void init(ServletConfig config) throws ServletException {
        DEBUG("Server starts");
        this.test = "hohoho " + System.currentTimeMillis();
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletOutputStream out = resp.getOutputStream();

        out.write(test.getBytes());

        out.flush();
        out.close();
    }
}

事实上,servlet 容器只为每个 servlet 创建一个实例。这有助于您在 servlet 成员变量中保存状态。然而,这并不意味着 servlet 容器不能使用同一个 servlet 实例来同时处理多个请求。这就是 servlet 包含(包括 Tomcat)所做的。因此,您的 servlet 必须是线程安全的。详情请参考这篇文章:http://tutorials.jenkov.com/java-servlets/servlet-concurrency.html

每个HttpServlet只有一个实例,它的init()方法只在构造HttpServlet时被调用一次。然而,doGet() 是在不同的线程中为每个请求调用的,并且可以并行发生。

我对你的问题有以下看法。

a) 是的,至少从 tomcat 7 onwards.For tomcat 6(annotation support),你将不得不查看规格。

b)关于在并行线程中执行,servlet默认不是线程安全的,为了保证线程安全,Servlet的service()方法不应该访问任何成员变量,除非这些成员变量本身是线程安全的。

有关线程安全的更多信息:Servlet Thread Safety