我需要一个解决方案来正确停止 Java 中的线程。
我有 IndexProcessor
实现 Runnable 接口的类:
public class IndexProcessor implements Runnable {
private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);
@Override
public void run() {
boolean run = true;
while (run) {
try {
LOGGER.debug("Sleeping...");
Thread.sleep((long) 15000);
LOGGER.debug("Processing");
} catch (InterruptedException e) {
LOGGER.error("Exception", e);
run = false;
}
}
}
}
我有 ServletContextListener
启动和停止线程的类:
public class SearchEngineContextListener implements ServletContextListener {
private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);
private Thread thread = null;
@Override
public void contextInitialized(ServletContextEvent event) {
thread = new Thread(new IndexProcessor());
LOGGER.debug("Starting thread: " + thread);
thread.start();
LOGGER.debug("Background process successfully started.");
}
@Override
public void contextDestroyed(ServletContextEvent event) {
LOGGER.debug("Stopping thread: " + thread);
if (thread != null) {
thread.interrupt();
LOGGER.debug("Thread successfully stopped.");
}
}
}
但是当我关闭 tomcat 时,我在 IndexProcessor 类中遇到异常:
2012-06-09 17:04:50,671 [Thread-3] ERROR IndexProcessor Exception
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at lt.ccl.searchengine.processor.IndexProcessor.run(IndexProcessor.java:22)
at java.lang.Thread.run(Unknown Source)
我正在使用 JDK 1.6。所以问题是:
我怎样才能停止线程而不抛出任何异常?
PS 我不想使用 .stop();
方法,因为它已被弃用。
原文由 Paulius Matulionis 发布,翻译遵循 CC BY-SA 4.0 许可协议
在
IndexProcessor
类中,您需要一种设置标志的方法,该标志通知线程它将需要终止,类似于变量run
您刚刚在类范围内使用的变量。当您希望停止线程时,您可以设置此标志并在线程上调用
join()
并等待它完成。通过使用 volatile 变量或使用与用作标志的变量同步的 getter 和 setter 方法,确保标志是线程安全的。
然后在
SearchEngineContextListener
: