如何在 Java 中正确停止线程? [英] How to properly stop the Thread in Java?

查看:26
本文介绍了如何在 Java 中正确停止线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一个解决方案来正确停止 Java 中的线程.

I need a solution to properly stop the thread in Java.

我有实现 Runnable 接口的 IndexProcessor 类:

I have IndexProcessorclass which implements the Runnable interface:

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 类:

And I have ServletContextListener class which starts and stops the thread:

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 类出现异常:

But when I shutdown tomcat, I get the exception in my IndexProcessor class:

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.所以问题是:

I am using JDK 1.6. So the question is:

如何停止线程而不抛出任何异常?

How can I stop the thread and not throw any exceptions?

P.S. 我不想使用 .stop(); 方法,因为它已被弃用.

P.S. I do not want to use .stop(); method because it is deprecated.

推荐答案

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

In the IndexProcessor class you need a way of setting a flag which informs the thread that it will need to terminate, similar to the variable run that you have used just in the class scope.

当你想停止线程时,你设置这个标志并在线程上调用 join() 并等待它完成.

When you wish to stop the thread, you set this flag and call join() on the thread and wait for it to finish.

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

Make sure that the flag is thread safe by using a volatile variable or by using getter and setter methods which are synchronised with the variable being used as the flag.

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 中正确停止线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆