如何正确停止Java中的线程?

我需要一个解决方案来正确停止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();方法,因为它已过时。

回答:

IndexProcessor类中,你需要一种设置标志的方法,该标志通知线程它将需要终止,类似于run你刚刚在类范围中使用的变量。

当你希望停止线程时,可以设置该标志并join()在线程上调用并等待其完成。

通过使用volatile变量或使用与用作变量的变量同步的getter和setter方法,确保该标志是线程安全的。

public class IndexProcessor implements Runnable {

private static final Logger LOGGER = LoggerFactory.getLogger(IndexProcessor.class);

private volatile boolean running = true;

public void terminate() {

running = false;

}

@Override

public void run() {

while (running) {

try {

LOGGER.debug("Sleeping...");

Thread.sleep((long) 15000);

LOGGER.debug("Processing");

} catch (InterruptedException e) {

LOGGER.error("Exception", e);

running = false;

}

}

}

}

然后在SearchEngineContextListener

public class SearchEngineContextListener implements ServletContextListener {

private static final Logger LOGGER = LoggerFactory.getLogger(SearchEngineContextListener.class);

private Thread thread = null;

private IndexProcessor runnable = null;

@Override

public void contextInitialized(ServletContextEvent event) {

runnable = new IndexProcessor();

thread = new Thread(runnable);

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) {

runnable.terminate();

thread.join();

LOGGER.debug("Thread successfully stopped.");

}

}

}

以上是 如何正确停止Java中的线程? 的全部内容, 来源链接: utcz.com/qa/425226.html

回到顶部