我的样子让我心烦意乱。我已经在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。
谢谢!
答案 0 :(得分:0)
对于未在分布式环境中托管的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中所述:
无需覆盖此方法