Best way to create a background thread in java

20.2k views Asked by At

What is the best way to create a background thread that will run every 15 minutes to get the data from the database?

Below is the code I have which will work fine I guess in production but is there any other way better that I have or something that I should be aware of?

private static void checkDatabaseEveryXMinutes() {
    new Thread() {
        public void run() {
            while (true) {
                try {
                    Thread.sleep(checkingAfterEveryXMinutes);
                    getDataFromDatabase();
                } catch (InterruptedException ex) {
                    //log here
                } catch (Exception e) {
                    //log here
                }
            }
        }
    }.start();
}

Is there any disadvantage in using the above code. And how does ScheduledExecutorService compares with TimerTask?

Which way is better?

Any example basis on my code will be appreciated on this if there are any better approach.

3

There are 3 answers

7
Alper Akture On BEST ANSWER

ScheduledExecutorService will return you a Future that has an additional method to check if the Runnable completed. Both have methods for canceling the Runnable. For repeated task like this, checking if it's done, is probably not going to be of much use. However, it was introduced with jdk 1.5 concurrency api, which should definitely be used in place of older concurrency/thread api's (Timer and TimerTask were jdk 1.3). They will be more robust, and better performant. They have a very similar example as your use case in the java doc here.

here's a sample:

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class ScheduledTaskExample {
    private final ScheduledExecutorService scheduler = Executors
        .newScheduledThreadPool(1);

    public void startScheduleTask() {
    /**
    * not using the taskHandle returned here, but it can be used to cancel
    * the task, or check if it's done (for recurring tasks, that's not
    * going to be very useful)
    */
    final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(
        new Runnable() {
            public void run() {
                try {
                    getDataFromDatabase();
                }catch(Exception ex) {
                    ex.printStackTrace(); //or loggger would be better
                }
            }
        }, 0, 15, TimeUnit.MINUTES);
    }

    private void getDataFromDatabase() {
        System.out.println("getting data...");
    }

    public void shutdowh() {
        System.out.println("shutdown...");
        if(scheduler != null) {
            scheduler.shutdown();
        }
    }

    public static void main(String[] args) {
        final ScheduledTaskExample ste = new ScheduledTaskExample();
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                ste.shutdowh();
            }
        });
        ste.startScheduleTask();

    }
}
0
Rahul Tripathi On

You can try using java.util.TimerTask and java.util.Timer

Example is here:-

Timer t = new Timer();

t.scheduleAtFixedRate(
    new TimerTask()
    {
        public void run()
        {
            System.out.println("3 seconds passed");
        }
    },
    0,      // run first occurrence immediately
    3000);
0
ssdimmanuel On

tieTYT is right. If you are using it in an application server, you can use the ejbtimer service of the specific server