Nik*_*yap 5 java tomcat windows-services servlets
这是我之前的问题的后续跟进.
Tomcat 5.0.28有一个错误,即关闭时容器没有调用Servlet的destroy()方法.这在Tomcat 5.0.30中得到修复,但如果Servlet的destroy()方法有一个System.exit(),则会导致Tomcat windows服务抛出错误1053并拒绝正常关闭(有关详细信息,请参阅上面的链接)这个错误)
任何人都知道是否:
在Servlet的destroy()方法中调用System.exit()强制终止任何非守护进程线程是一个好主意?
如果Servlet的destroy()方法中存在System.exit(),为什么Tomcat 5.0.30和(包括Tomcat 6.xx的更高版本)无法正常关闭.
mat*_*t b 16
在Servlet的destroy()方法中调用System.exit()强制终止任何非守护进程线程是一个好主意?
这绝对不是一个好主意 - 这是一个可怕的想法.destroy()当servlet停止服务时调用该方法,这可能由于多种原因而发生:servlet/webapp已停止,webapp正在取消部署,webapp正在重新启动等.
System.exit()关闭整个JVM!为什么要简单地因为卸载一个servlet而强行关闭整个服务器?
如果Servlet的destroy()方法中存在System.exit(),为什么Tomcat 5.0.30和(包括Tomcat 6.xx的更高版本)无法正常关闭.
可能是为了防止这样的危险行为.
您不应该编写代码,假定您的代码/应用程序是服务器上运行的唯一内容.
Jar*_*red 12
你问了两个问题:
问题1:在Servlet的destroy()方法中调用System.exit()强制杀死任何非守护进程线程是个好主意吗?
在任何与servlet相关的方法中调用System.exit()总是100%不正确.您的代码不是JVM中运行的唯一代码 - 即使您是唯一运行的servlet(servlet容器具有在JVM真正退出时需要清理的资源.)
处理这种情况的正确方法是在destroy()方法中清理线程.这意味着以允许您以正确方式轻轻地停止它们的方式启动它们.这是一个例子(MyThread是你的一个线程,并扩展了ServletManagedThread):
public class MyServlet extends HttpServlet {
private List<ServletManagedThread> threads = new ArrayList<ServletManagedThread>();
// lots of irrelevant stuff left out for brevity
public void init() {
ServletManagedThread t = new MyThread();
threads.add(t);
t.start();
}
public void destroy() {
for(ServletManagedThread thread : threads) {
thread.stopExecuting();
}
}
}
public abstract class ServletManagedThread extends Thread {
private boolean keepGoing = true;
protected abstract void doSomeStuff();
protected abstract void probablySleepForABit();
protected abstract void cleanup();
public void stopExecuting() {
keepRunning = false;
}
public void run() {
while(keepGoing) {
doSomeStuff();
probablySleepForABit();
}
this.cleanup();
}
}
Run Code Online (Sandbox Code Playgroud)
还有值得注意的是,有一些线程/并发库可以帮助解决这个问题 - 但如果你真的有一些在servlet初始化时启动并且应该运行直到servlet被销毁的线程,这可能就是你需要的全部内容.
问题2:如果Servlet的destroy()方法中存在System.exit(),为什么Tomcat 5.0.30和(包括Tomcat 6.xx的更高版本)无法正常关闭?
没有更多的分析,很难确定. 微软表示,当Windows要求服务关闭时,会出现错误1053,但请求超时.这将使Tomcat内部发生的事情变得非常糟糕.我当然会怀疑你的电话System.exit(可能是罪魁祸首.Tomcat(特别是Catalina)确实在VM上注册了一个关闭钩子(see org.apache.catalina.startup.Catalina.start()至少在5.0.30中).当你调用时,JVM会调用那个关闭钩子System.exit().关闭挂钩委托给正在运行的服务,因此可能需要每个服务执行大量工作.
如果关闭hooks(triggered by your System.exit())无法执行(它们死锁或类似的东西),那么很容易理解错误1053发生的原因,给定Runtime.exit(int)方法的文档(从中调用System.exit()):
如果在虚拟机开始其关闭序列后调用此方法,则如果正在运行关闭挂钩,则此方法将无限期地阻塞.如果已经运行了关闭挂钩并且已启用了退出终结,则此方法如果状态为非零,则使用给定的状态代码暂停虚拟机; 否则,它会无限期地阻止.
这种"无限期阻塞"行为肯定会导致错误1053.
如果您想要比此更完整的答案,您可以下载源代码并自行调试.
但是,我愿意打赌,如果你正确处理线程管理问题(如上所述),你的问题就会消失.
简而言之,将System.exit()调用留给Tomcat - 这不是你的工作.
| 归档时间: |
|
| 查看次数: |
13488 次 |
| 最近记录: |