好问题
Good  Question
  • 首 页
  • 问题
    • PHP
    • JAVA
    • CPlusPlus
    • C#
    • SQL
  • 关 于
  • 联 系
如何正确停止Java中的线程? 关闭 返回上一级  

如何正确停止Java中的线程?
+ 查看更多

发布日期:2018-02-23 16:36
分类:JAVA
浏览次数:123
我需要一个解决方案来正确地停止线程在Java。
我有IndexProcessorclass实现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类启动和停止线程:
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。所以问题是:
如何停止线程,不抛出任何异常?
P.S。我不想使用.stop();方法,因为它已被弃用。
 
回答:
 
在IndexProcessor类中,您需要一种设置标志的方法,通知线程需要终止它,类似于您在类范围中使用的变量运行。
当你想停止线程,你设置这个标志,并调用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应用来使用Gamil,Yahoo或者Hotmail发送一个邮件?
如何在JSP中导入类?下一篇
下一篇如何在JSP中导入类?

最新文章

  • 函数`__construct`用来干嘛的
    发布日期:2018-03-26
  • 通过访客的IP得到他们的地区
    发布日期:2018-03-26
  • 合并两个PHP对象的最好的方法是什么?
    发布日期:2018-03-26
  • 该如何把一该如何把一个对象转化成数组?
    发布日期:2018-03-26
  • 什么是输出缓冲区?
    发布日期:2018-03-26
  • 在PHP中怎么把用逗号分隔的字符串分隔在一个数组里?
    发布日期:2018-03-26
  • 在PHP中使用foreach循环时查找数组的最后一个元素
    发布日期:2018-03-26
关于好问
收集整理一些有用的问题和回答,造福中国的程序旺和IT喵们!
友情链接
起飞页 
相关信息
版权声明
Copyright © 2016 - 2022  苏州卡达网络科技有限公司 备案号:苏ICP备09008221号