I have got a requirement in which i need to execute a function at specified time set by the user.The function contains the code to generate a pdf file from database and save it into local drive of the machine..
Here the time needs to be set by the user and it may be changed depending on his requirement.
I have never used timer class..
I have a code snippet which i got from google but i am not getting how to set the user specific time details for function execution in this code ..
Here is the code snippet..
class ReportGenerator extends TimerTask {
public void run() {
System.out.println("Generating report");
//TODO generate report
}
}
class MainApplication {
public static void main(String[] args) {
Timer timer = new Timer();
Calendar date = Calendar.getInstance();
date.set(
Calendar.DAY_OF_WEEK,
Calendar.SATURDAY);
date.set(Calendar.HOUR, 0);
date.set(Calendar.MINUTE, 0);
date.set(Calendar.SECOND, 0);
date.set(Calendar.MILLISECOND, 0);
// Schedule to run every Sunday in midnight
timer.schedule(
new ReportGenerator(),
date.getTime(),
1000 * 60 * 60 * 24 * 7);
}
}
I am also not getting the meaning of this code snippet..what does this means??
timer.schedule(
new ReportGenerator(),
date.getTime(),
1000 * 60 * 60 * 24 * 7);
}
In the above code snippet the given function will execute on every saturday .
Please help me .Any idea is heartely welcomed ...
Thanks in advance..
Okay, so I looked a bit into the Timer class and found your approach to be almost correct. You'll need to edit your code a little bit to get the wanted functionality.
Calendar calendar = Calendar.getInstance();
date.set(Calendar.DAY_OF_WEEK, getUserInputDay()); //
calendar.set(Calendar.HOUR_OF_DAY, getUserInputHour());
calendar.set(Calendar.MINUTE, getUserInputMinute());
calendar.set(Calendar.SECOND, getUserInputSeconds());
Date time = calendar.getTime();
timer = new Timer();
timer.schedule(new ReportGenerator(), time);
This will start a timer that launches the "ReportGenerator" at the stated time. You'll have to figure out yourself how to get the input from the user (should be fairly simple!)
There is a good library called quartz that I can recommend. Its main purpose is starting jobs at a given time.
Related
I am attempting to create a scheduled job which runs every 5 minutes from 7 AM to 22 PM everyday. For example, it should runs at 7:00, 7:05, 7:10 ... 21:55, and then it should stop at 22:00. On the next day, it runs the same schedule again and so on.
I have found this example which shows how to use ScheduledExecutorService to start a task at particular time.
How to run certain task every day at a particular time using ScheduledExecutorService?
I referred to the answer and write my code like below:
(I am using Java 7)
class Scheduler {
private ScheduledExecutorService executors;
public static void main(String[] arg) {
Runnable task = new Runnable() {
#Override
public void run() {
...DO SOMETHING...
}
};
// Get how many seconds before the next start time (7AM).
long initDelay = getInitialDelay(7);
ScheduledExecutorService executors = Executors.newSingleThreadScheduledExecutor();
executors.scheduleAtFixedRate(task, initDelay, (60 * 5), TimeUnit.SECONDS);
}
private static long getInitialDelay(int hour) {
Calendar calNow = Calendar.getInstance();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
long diff = cal.getTimeInMillis() - calNow.getTimeInMillis();
if (diff < 0) {
cal.add(Calendar.DAY_OF_MONTH, 1);
diff = cal.getTimeInMillis() - calNow.getTimeInMillis();
}
return diff / 1000;
}
}
My above code starts at 7 AM and runs every 5 minutes perfectly. However, how can I do to control ScheduledExecuterService to stop the task at 22 PM and then start again at 7 AM on the next day?
Or, is there any better other way to run a task during particular period of time everyday?
A fixed scheduled executor service cannot alter its timing.
So use the single-run non-fixed scheduled executor service. Call ScheduledExecutorService::schedule. On its first run, check the current time. If before the end of the work day, call the same method schedule again, passing a delay of five minutes. If after the end of the work day, pass a delay of eight hours, the amount of time until the new work day starts.
So, a simple little trick. Each run of your runnable schedules the next run, endlessly.
I have the code below that prints a text every day. However I would like it to print the text only on -- for example -- 8 o'clock in the morning.
String text = "Test";
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println(text);
}
}, 0, 1000 * 60 * 60);
In my code, the print time depends on the time I run the code and the code of course does not consider the daylight saving time changes etc.
Use public void schedule(TimerTask task, Date time) of Timer
i want to run my code every wednesday each week at midnight.
public class Autonom extends TimerTask {
public static void main(String[] args) {
Timer timer = new Timer();
Calendar data = Calendar.getInstance();
data.set(Calendar.DAY_OF_WEEK, Calendar.WEDNESDAY);
data.set(Calendar.HOUR_OF_DAY, 0);
data.set(Calendar.MINUTE, 0);
data.set(Calendar.SECOND, 0);
data.set(Calendar.MILLISECOND, 0);
timer.schedule(new Autonom(), data.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS));
}
#Override
public void run() {
...
}
}
The problem is that when i start this code, the run method is execute each time. So whats the problem?
You use the current time and set it to midnight on Wednesday. Since we are friday today, wednesday is in the past.
From the doc, you can see what happen in that case
if the scheduled first time is in the past, it is scheduled for immediate execution.
If you want to wait the next wednesday to start the execution, increment the week.
data.add(Calendar.WEEK_OF_YEAR, 1);
This will be a date in the futur and will wait until then to start the first execution.
I am looking for the best way in Java to monitor the computer clock (the minutes) and to fire off a method/thread every time it changes.
So if the time is 13:20 and it changes to 13.21 then do something. So any time there is a minute change some code gets fired.
What is the best way to listen to the minute section of the clock for changes ?
Thanks,
Richard
Find the current system time using System.currentTimeMillis()
Calculate how many milliseconds until the next minute
Schedule a TimerTask on a Timer to run in that number of milliseconds in the future
In that TimerTask's event handler schedule a new reoccurring TimerTask to run every 60,000 milliseconds.
int milisInAMinute = 60000;
long time = System.currentTimeMillis();
Runnable update = new Runnable() {
public void run() {
// Do whatever you want to do when the minute changes
}
};
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
update.run();
}
}, time % milisInAMinute, milisInAMinute);
// This will update for the current minute, it will be updated again in at most one minute.
update.run();
Sounds like a job for Quartz. You can do this using the following cron expression:
0 * * * * ?
Date d = new Date(System.currentTimeMillis());
Then you can get the minutes by d.getMinutes(). Have a check running in a thread waiting for the value of d.getMinutes() to change.
Finally after some trial and errors I have managed to make it work as I wanted.
But now I would like your advice to make the code more readable and simple it seems a made a lot of unnecessary code to archive what I wanted.
What this basicly do is, if you turn on the server app at a time a schedule task should be running, it will start the task and let it run for the time left from when it should have started otherwise it will be schedule to run at the hour it is supposed to run.
So if the schedule time is 13:00:00 and should run for 120 minutes and you start the app at 13:30 it will run for 90 minutes. If you start it after that time, it will be normally schedule for the next day 13:00:00.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
long start_time = calendar.getTimeInMillis() - System.currentTimeMillis();
if (start_time < 0)
{
long minutes = (start_time*-1) / (60 * 1000);
if (minutes > 0 && minutes < 120)
{
runTimeLeft = 120 - minutes;
ThreadPoolManager.getInstance().schedule(new Runnable()
{
public void run()
{
myTask();
}
}, 0);
}
else
runTimeLeft = 0;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour+24);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
start_time = calendar.getTimeInMillis() - System.currentTimeMillis();
}
ThreadPoolManager.getInstance().scheduleAtFixedRate(new Runnable()
{
public void run()
{
myTask();
}
}, start_time, 24 * 60 * 60 * 1000);
So my question here now is what could I improve on the above code ?
Instead of using java.util.Timer alone, try using it with TimerTask. There is a good article from IBM on this.
Have a look at this link: http://www.ibm.com/developerworks/java/library/j-schedule.html
The code is also shared and seems to work for trivial routine job.
Use this instead for your first method:
int interval = 24 * 60 * 60 * 1000; // might be long instead of int
ThreadPoolManager.getInstance().scheduleAtFixedRate(new Runnable()
{
public void run()
{
myTask();
}
}, interval, interval);
This will create a simple timer that will call myTask() in 24 hours, and then every 24 hours after.
Your other requirement is a little different, though. If I understand your description correctly, you basically want your app to always execute some task at 12:00 AM if it happens to be up and running. If you don't care about down-to-the-millisecond accuracy for this, you could achieve it very simply by starting a Timer with a one minute period and checking the current system time in each tick - when you hit 12:00 AM run your daily task.
A fancier way would involve interacting with the OS such that it makes callbacks to your application at pre-scheduled times (possibly even starting your app if necessary), but this kind of thing is OS/platform specific (which you didn't specify).
Update: I know nothing about Linux, but it looks like a cron job is what you're looking for. See this question:
Running a scheduled task written in java on a linux server