Java 停止Tomcat应用程序中的线程-哪种方法?
我使用下面的实现来停止Tomcat中的线程。代码是有效的,但我想知道两件事:Java 停止Tomcat应用程序中的线程-哪种方法?,java,multithreading,apache,tomcat,Java,Multithreading,Apache,Tomcat,我使用下面的实现来停止Tomcat中的线程。代码是有效的,但我想知道两件事: 是否有必要在MyConsumer.java的try语句中包含Thread.sleep() 我是否应该在(!Thread.currentThread().isInterrupted)时删除标志的概念并只检查,而不是检查布尔标志,running ServletContextListener: public final class ApplicationListener implements ServletContextLi
,而不是检查布尔标志,running
李>
ServletContextListener:
public final class ApplicationListener implements ServletContextListener {
private Thread thread = null;
private MyConsumer k = null;
public ApplicationListener() {
}
@Override
public void contextInitialized(ServletContextEvent event) {
k = new MyConsumer();
thread = new Thread(k);
thread.start();
}
@Override
public void contextDestroyed(ServletContextEvent event) {
if (thread != null) {
k.terminate();
try {
thread.join();
} catch (InterruptedException ex) {
Logger.getLogger(ApplicationListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class MyConsumer implements Runnable {
private volatile boolean running = true;
public MyConsumer() {
}
public void terminate() {
running = false;
}
@Override
public void run() {
while (running) {
try {
doStuff();
Thread.sleep((long) 1000);
} catch (InterruptedException ex) {
Logger.getLogger(MyConsumer.class.getName()).log(Level.SEVERE, null, ex);
running = false;
}
}
}
MyConsumer.java:
public final class ApplicationListener implements ServletContextListener {
private Thread thread = null;
private MyConsumer k = null;
public ApplicationListener() {
}
@Override
public void contextInitialized(ServletContextEvent event) {
k = new MyConsumer();
thread = new Thread(k);
thread.start();
}
@Override
public void contextDestroyed(ServletContextEvent event) {
if (thread != null) {
k.terminate();
try {
thread.join();
} catch (InterruptedException ex) {
Logger.getLogger(ApplicationListener.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class MyConsumer implements Runnable {
private volatile boolean running = true;
public MyConsumer() {
}
public void terminate() {
running = false;
}
@Override
public void run() {
while (running) {
try {
doStuff();
Thread.sleep((long) 1000);
} catch (InterruptedException ex) {
Logger.getLogger(MyConsumer.class.getName()).log(Level.SEVERE, null, ex);
running = false;
}
}
}
是否有必要在MyConsumer.java的try语句中包含Thread.sleep()
不可以。我想,睡眠调用是为了确保每次调用之间间隔1秒执行doStuff()
,而不是连续执行。如果您想要这1秒的间隔,您需要将睡眠呼叫留在那里。如果要连续执行doStuff()
,则需要删除睡眠
与其检查布尔标志running,不如删除标志的概念,只检查while(!Thread.currentThread().isInterrupted)
是的,我确实会这么做。它将消除对标志的需要,并允许尽快停止线程,而不必等待睡眠调用在1秒后返回。另一个优点是,您可以检查doStuff()
方法中的线程是否中断,以防它是一个长时间运行的方法,您希望尽快停止 你的线程没有理由仅仅为了检查中断而休眠。您可以在那里调用Thread.interupted()
关于booleanrunning
标志,它提供了与interrupted类似的功能,只是它不是由抛出InterruptedException的方法触发的。根据停止这些方法中的正常操作流是否合理,您应该使用一种或另一种机制,但不能同时使用这两种机制
有关如何使用中断的详细概述,请参阅。非常感谢。因此,在我的contextDestructed()中,我将添加对thread.interrupt()的调用。我是否仍然需要在thread.interrupt()之前调用thread.join()?另外,应该从contextDestroyed()调用thread.interrupt(),还是从MyConsumer类中的catch(InterruptedException ex)块调用thread.interrupt()?为了抛出eh InterruptedException,必须中断线程。因此,您需要从contextDestroyed()方法调用interrupt()。中断请求线程中断自身,并立即返回。因此,如果要等待线程终止后再从contextDestroyed()返回,则仍然需要加入调用。再次感谢您的帮助。