Tomcat执行服务已同步

时间:2017-04-20 21:33:02

标签: java tomcat servlets

我的样子让我心烦意乱。我已经在Java 9上创建了与Tomcat 9(8个相同)的新项目(同样在8上)。它只有一个servlet

@WebServlet(urlPatterns = "/*")
public class Servlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println(new Date().getTime() /1000 + " " + Thread.currentThread().getName() + " Start");
        /*long i = 0;

        while (i < 3000000000L) {
            if (i % 2 == 0) {
                i++;
            } else {
                i++;
            }
        }*/
        try {
            Thread.sleep(2000);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        System.out.println(new Date().getTime()/1000 + " " + Thread.currentThread().getName() + " Done");
    }
}

我所有的经验告诉我,该方法异步工作,但我在浏览器中通过3个选项卡调用servlet(尽可能同时),我在我的日志中有这张图片:

1492723549 http-nio-9999-exec-2 Start
1492723551 http-nio-9999-exec-2 Done
1492723551 http-nio-9999-exec-1 Start
1492723553 http-nio-9999-exec-1 Done
1492723553 http-nio-9999-exec-3 Start
1492723555 http-nio-9999-exec-3 Done

可以看出,每个请求都会锁定方法,直到完成为止。有人可以告诉我为什么吗?我真的希望3个同时开始,2秒后3个Dones。

谢谢!

1 个答案:

答案 0 :(得分:0)

根据servlet specification

  

对于未在分布式环境中托管的servlet(默认),   servlet容器每个servlet只能使用一个实例   宣言。但是,对于实现的servlet   在SingleThreadModel接口中,servlet容器可以实例化   多个实例来处理繁重的请求加载和序列化   对特定实例的请求。

     

在将servlet部署为应用程序的一部分的情况下   在部署描述符中标记为可分发,容器可以   每个Java Virtual每个servlet声明只有一个实例   机器(JVM)。但是,如果servlet位于可分发的应用程序中   实现SingleThreadModel接口,容器可以   在每个JVM中实例化该servlet的多个实例   容器

另外,here你可以找到一些关于tomcat的信息:

  

诸如Tomcat之类的Web服务器可以实例化任意多个实例   尽管数量通常很小(例如,1到1)   4)。 Web服务器本身就做出了决定。

因此,在您的应用中只有一个servlet实例是绝对正常的。

请确保您确实需要覆盖HttpServlet.service()方法,因为正如javadoc中所述:

  

无需覆盖此方法