我已经编写了一个部署在tomcat中的servlet。
public class myServlet extends HttpServlet {
public int NumberOfThreads = 0;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(NumberOfThreads);
NumberOfThreads++;
....
..a lot of code..
....
NumberOfThreads--;
}
}
现在,当我收到太多请求时,NumberOfThreads会继续上升并且永远不会再次下降。我的问题是每个请求在离开之前必须执行一些任务。
我只是不明白为什么会这样。是不是有些线程在路上丢失了?我真的需要每个请求说再见。
由于
答案 0 :(得分:1)
正如您所说的那样需要很长时间并且请求被取消(在您的评论中):是的,整个doGet
将被执行,即使用户取消了请求:请求取消仅限在HTTP级别上。但是,当取消请求时,HTTP连接可能会关闭,导致实际想要写入响应的输出流时出现异常。
结合已经给出的其他答案:
伪代码:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
synchronized(this){NumberOfThreads++;}
doSomething();
} finally {
synchronized(this){NumberOfThreads--;}
}
}
另外,请注意在实际的http连接器线程中长时间执行会阻止所有后续的http请求 - 触发后台处理并在稍后的HTTP请求中查询后台进程可能是个好主意。这样,您也可以对多个调用进行排队,而不是同时启动大量后台线程。请记住,HTTP请求处理程序数量有限。
我假设try / finally将是你的主要问题(或代码中的无限循环) - 同步将解决罕见的竞争条件,特别是当你谈到很多时在这个servlet中执行的代码。
答案 1 :(得分:0)
您需要将修改同步到NumberOfThreads
public class myServlet extends HttpServlet {
public int NumberOfThreads = 0;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println(NumberOfThreads);
synchronized(this){NumberOfThreads++;}
....
..a lot of code..
....
synchronized(this){NumberOfThreads--;}
}
}
答案 2 :(得分:0)
不同的servlet线程正在缓存NumberOfThreads
。您必须将其标记为volatile
。
public volatile int NumberOfThreads = 0;
但是,我觉得有更好的方法来做你可能希望用这段代码实现的目标。
答案 3 :(得分:0)
你做错了。
System.out.println(ManagementFactory.getThreadMXBean().getThreadCount());
或者,只需使用JMX / JConsole。