0

I am writing a java ee application using jsf. I defined some backround processes such as upating the database periodically etc. Here is the code:

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);
        }
}       
}

And the class:

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);
            }

        }
    };

The problem is, after program finishes, and even though i close project, and so my database keeps being updated. So how can i kill the thread when program closes?

Thanks

yrazlik
  • 10,411
  • 33
  • 99
  • 165
  • 1
    Don't use explicit Threads in JEE environments. Rely on the provided facilities instead: http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html – Dominik Sandjaja Jul 12 '13 at 10:59
  • 1
    Bad idea!! Related: http://stackoverflow.com/questions/7499534/applicationscope-bean-that-uses-a-timertask-sheduler-good-or-bad/7499769#7499769 – BalusC Jul 12 '13 at 11:21

2 Answers2

2

As far as I can see, you should add a method to your AppServletContextListener called contextDestroyed(ServletContextEvent). Store your zamanli object as instance variable for the AppServletContextListener class and use the contextDestroyed method to stop the zamanli.

But in general I would recommend not to start your own threads in a Java EE environment.

mthmulders
  • 9,483
  • 4
  • 37
  • 54
2

Use a ScheduledExecutorService instead of a Timer, and use a ThreadFactory which spawns a daemon thread instead of a normal 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);

Make it so that the service reference is available to contextDestroyed(), that will be even easier; you then don't have to use daemon threads and can just call service.shutdownNow() in it.

Community
  • 1
  • 1
fge
  • 119,121
  • 33
  • 254
  • 329