关闭项目后线程仍然退出,如何杀死它?

时间:2013-07-12 10:43:09

标签: java multithreading jsf

我正在使用jsf编写一个java ee应用程序。我定义了一些后台进程,例如定期更新数据库等。以下是代码:

public class AppServletContextListener implements ServletContextListener{
    @Override
public void contextInitialized(ServletContextEvent arg0) {
    zamanli zm = new zamanli();
        try {   
            zm.programBasla();
        } catch (MalformedURLException ex) {
            Logger.getLogger(AppServletContextListener.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(AppServletContextListener.class.getName()).log(Level.SEVERE, null, ex);
        }
}       
}

上课:

public class zamanli {
    public void programBasla() throws MalformedURLException, IOException {
    int delay = 5000; //5 sn sonra başlar
    int period = 600000; //10 dkda tekrar
    Timer timer = new Timer();
    TimerTask task = new TimerTask() {
        @Override
        public void run() {

            Runtime r = Runtime.getRuntime();
            Process p = null;

            try {
                //  p = r.exec("c:\\WINDOWS\\system32\\calc");
                System.out.println(Now());

            } catch (Exception e) {

                System.out.println("Çalışmadı");
            }
            try {
                getCurrentExchangeValue();
            } catch (MalformedURLException ex) {
                Logger.getLogger(zamanli.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex) {
                Logger.getLogger(zamanli.class.getName()).log(Level.SEVERE, null, ex);
            }

        }
    };

问题是,在程序完成后,即使我关闭项目,所以我的数据库不断更新。那么当程序关闭时如何杀死线程呢?

由于

2 个答案:

答案 0 :(得分:2)

据我所知,您应该为名为AppServletContextListener的{​​{1}}添加方法。将contextDestroyed(ServletContextEvent)对象存储为zamanli类的实例变量,并使用AppServletContextListener方法停止contextDestroyed

但总的来说,我建议不要在Java EE环境中启动自己的线程。

答案 1 :(得分:2)

使用ScheduledExecutorService代替Timer,并使用ThreadFactory生成daemon thread而非正常线程:

private static final ThreadFactory THREAD_FACTORY = new ThreadFactory()
{
    private final ThreadFactory factory = Executors.defaultThreadFactory();

    @Override
    public Thread newThread(final Runnable r)
    {
        final Thread ret = factory.newThread(r);
        ret.setDaemon(true);
        return ret;
    }
};

// ...
private final ScheduledExecutorService service
    = Executors.newSingleThreadScheduledExecutor(THREAD_FACTORY);

//...
service.scheduleAtFixedRate(etc etc);

使service引用可供contextDestroyed()使用,这样会更容易;然后,您不必使用守护程序线程,只需在其中调用service.shutdownNow()即可。