Best way to create a background thread in java
Asked Answered
I

3

7

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.

Isomerous answered 21/8, 2013 at 19:16 Comment(4)
docs.oracle.com/javase/7/docs/api/java/util/concurrent/…Caddis
@Caddis thanks for suggestion. Can I ask you why are you recommending this as compared to my solution that I have above?Isomerous
@TechGeeky Easy. With your approach, you had to write your own loop to sleep and resubmit. With a ScheduledExecutorService, you simply scheduleAtFixedRate (or scheduleWithFixedDelay), and everything is automatically taken care of.Zoolatry
@ChrisJester-Young, Thanks for the help. Can you provide a simple example basis on my code using that? As nobody has given an example how to use that. So any help will be appreciated on that..Isomerous
M
11

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

    }
}
Microcrystalline answered 21/8, 2013 at 20:42 Comment(7)
+1 because I agree with your answer, but as the OP said in the question comments, you might want to write them an example just so they don't shoot themself in the foot. :-)Zoolatry
can't argue with that I guess.. added the example :)Microcrystalline
Added an important edit! Make sure to put a try/catch around the critical code, incase an exception is thrown. Without that, and exception will kill the thread and it will stop it's timed execution.Microcrystalline
It works perfectly. Thanks Alper. But I don't understand why my original won't work. I was using traditional Thread class to create the runnable. and created the class and run() it. The thread runs. But it block all my other calls. The original main thread is not execute afterwards.Klingensmith
Hm, that should not happen, but it's hard to say why without seeing your code :-/ if you want to post it (maybe a new question, and then the link here) I could take a look.Microcrystalline
Can you edit the answer to add a statement to shutdown the thread on application shutdown/failure? Otherwise there may be the chance of creating a memory leak.Tidings
@anatolics, added a shutdown.Microcrystalline
Y
2

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);
Yearwood answered 21/8, 2013 at 19:18 Comment(0)
S
0

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

Splash answered 21/8, 2013 at 19:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.