I have a purpose for an application to run a daemon in my web application. The application is running with Struts1 on a tomcat7 server using Java7.This is what it does:Launch itself when the application is loadedevery minutes does a task (the sysout in the code)when the application stops, it stops the timer and let the task 10 sec max to finish its process if neededIn the web.xml file i have these lines to launch the process:<listener>    <listener-class>com.toto.tata.applicationlayer.BiuDeamon</listener-class></listener>And here is the code:package com.toto.tata.applicationlayer;import java.util.Date;import java.util.Timer;import java.util.TimerTask;import java.util.concurrent.TimeUnit;import javax.servlet.ServletContextEvent;import javax.servlet.ServletContextListener;import org.apache.log4j.Logger;public class BiuDeamon implements ServletContextListener {    private static boolean isDaemonWorking = false;    private static Timer timer;    private static TimerTask timerTask;    static {        timerTask = new TimerTask(){            public void run() {                if (!isDaemonWorking) {                    try {                        isDaemonWorking = true;                        System.out.println(I RUN);                        isDaemonWorking = false;                    } catch (Throwable e) {                        ex.printStackTrace();                    }                }            }        };    }    public BiuDeamon() {        super();    }    public void contextInitialized(ServletContextEvent a_event) {        timer = new Timer();        timer.schedule(timerTask, new Date(), 60000);    }    public void contextDestroyed(ServletContextEvent a_event) {        // we stop the timer        timer.cancel();        // we let the timertask 10 sec to stop its processing        int i=0;        for (; i<10; i++) {            if (isDaemonWorking) {                try {                    TimeUnit.SECONDS.sleep(1);                } catch(InterruptedException ex) {                    Thread.currentThread().interrupt();                }            } else {                break;            }        }        // we kill it if needed        if (i==10)            timerTask.cancel();    }}I know my code is working because I have tested it, but I wonder if there is a better way to achieve what I want. Any comments / examples will be appreciated :)
Best way to create a daemon in a JavaWeb application
java
Using a ServletContextListener is a good solution, I would use the same.I would consider using a ScheduledExecutorService here (Executors.newScheduledThreadPool(1)). It has some advantages:It has a scheduleWithFixedDelay method as well as scheduleAtFixedRate. Using one of these describes what's the developer's purpose. Currently its not completely obvious or explicit.It supports shutdown and awaitTermination. awaitTermination returns immediately when your task finishes, no need to wait complete seconds.awaitTermination returns false on timeout when you can call shutdownNow which interrupts the thread of the task.It does not need manual and error-prone synchronization (see the next point).newScheduledThreadPool can get a ThreadFactory. You can set a UncaughtExceptionHandler to handle uncatched exceptions with that factory. (See also this answer too.)Usage of isDaemonWorking is not thread-safe. It is used by the timer's thread (inside the TimerTask.run method) as well as the ServletContextListener. Without any synchronization you risk that threads will not see each other's modification.[...] synchronization has no effect unless both read and write operations are synchronized.From Effective Java, 2nd Edition, Item 66: Synchronize access to shared mutable data.You could invert the if condition here:for (; i<10; i++) {    if (isDaemonWorking) {        try {            TimeUnit.SECONDS.sleep(1);        } catch(InterruptedException ex) {            Thread.currentThread().interrupt();        }    } else {        break;    }}It would keep the code flatten:for (; i < 10; i++) {    if (!isDaemonWorking) {        break;    }    try {        TimeUnit.SECONDS.sleep(1);    } catch (InterruptedException ex) {        Thread.currentThread().interrupt();    }}I guess if you put the isDaemonWorking = false into a finally block:try {    isDaemonWorking = true;    System.out.println(I RUN);} catch (Throwable e) {    e.printStackTrace();} finally {    isDaemonWorking = false;}then you could replaceif (i == 10)    timerTask.cancel();withif (isDaemonWorking) {    timerTask.cancel();}and use an usual for (int i = 0; i < 10; i++) loop too.I would not think that initialization of TimerTask should be in a static block. The timer and isDaemonWorking also could be instance fields. I think (and I would expect that) the servlet container calls contextDestroyed on the same instance than contextInitialized.Variable names in Java usually camelCase, so a_event should be aEvent or just event here:public void contextInitialized(ServletContextEvent a_event) {I guess you have a typo here: BiuDeamon (it should be BuiDaemon).