我有一个 Servlet 来显示登录页面,当我输入 URL 时,Servlet 已由单独的线程指定并完成工作。但即使在提交响应后(即在完成作业后(,线程仍然处于活动状态,为什么这样做?活动状态在页面中收到响应后显示为 True。
法典:
public class LoginNew extends HttpServlet implements Runnable {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter writter = response.getWriter();
writter.println(
"<!DOCTYPE html>" +
"<html>" +
"<form>" +
"<div style="text-align:center">UserName :<input type="text" name="UserName"><br>" +
"<div style="text-align:center">Password :<input type="password" name="Password"><br>" +
"<div style="text-align:center">TimeOut Interval :<input type="text" name="TimeOut"><br>" +
"<div style="text-align:center">No TimeOut :<input type="checkbox" name="NoTimeout" value="1"> NoTimeout <br><br>" +
"<input type="submit" formaction="Home" formmethod="post" value="Login" />" +
" "+
"<input type="submit" formaction="SignUp" formmethod="post" value="SignUp" />" +
"</form>" +
"</body>" +
"</html>"
);
Thread.currentThread().sleep(60000);
System.out.println("After Commitment Thread -> "+Thread.currentThread().getName()+" Alive Status--> "+Thread.currentThread().isAlive());
}
}
根据您的代码, 看起来您正在检查线程内部线程的活性,当然它在那一刻是活动的。为了更清楚起见,您可以使用VisualVM程序,它显示程序的每个生成线程以及其他有用的信息。
这里有许多误解和奇怪之处:
-
如果可以调用
Thread.currentThread().isAlive()
,它总是会返回true
。 如果当前线程不活动,则它无法执行任何操作。 -
典型的 servlet 容器不会终止请求线程。 那将是低效的。 相反,当请求完成时,请求线程将返回到池中,以便它可用于下一个请求。
-
"即使在做出回应之后;即在完成工作后..."。这不是"作出回应"的意思。 它实际上意味着HTTP响应标头已被写入。 这意味着无法再更改响应代码或更新任何响应标头。 (在您的示例中,响应是在您调用
getWriter
时提交的。 -
事实上,在关闭
PrintWriter
之前,响应实际上无法完成。 这可能是service
方法中的显式关闭,也可能是在service
调用返回后将发生的隐式关闭。 -
在您的示例中,您在写入响应正文和返回之间休眠了 60 秒。 由于您在写入后没有刷新
Writer
,这可能意味着客户端(例如浏览器(必须等待 60 秒才能到达完整的正文。 -
sleep
还将锁定其中一个请求线程 60 秒。 如果同时执行此操作的请求太多,则可能会占用所有线程。 这是个坏主意。