Suppose in a directory there are N number of files, we need to display/log the number of files present after every one hour.
ex: No of files at 10:00 AM :25
No of files at 11:00 AM :22
so we need to create a timed action, I thought of using Thread.sleep(XXX) to suspend the Thread for 1 hour and then again get the count and print.
please suggest better alternatives.
Use TimerTask - A task that can be scheduled for one-time or repeated execution by a Timer.
import java.io.File;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimeIt {
public static void main(final String[] args) throws InterruptedException {
final TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("Task performed on " + new Date());
// Complete lo
final int count = new File("/tmp/").list().length;
System.out.println(count);
}
};
final Timer timer = new Timer("Timer");
timer.scheduleAtFixedRate(task, 1000L, 1000L);
Thread.sleep(1000L * 2);
timer.cancel();
}
}
TimerTask Java Doc
Java Timer and TimerTask
Related
I am trying to execute a task periodically. For example:
class MyTimerTask implements TimerTask
{
public void run() {
// Some actions to perform
}
Timer cleaner = new Timer(true);
cleaner.scheduleAtFixedRate(new MyTimerTask(), 0, PURGE_INTERVAL);
}
However, the run method is executing only once. But if I put the first time delay as 10 seconds, then the run method doesn't execute even once.
Example:
cleaner.scheduleAtFixedRate(new MyTimerTask(), 10, PURGE_INTERVAL);
This sounds like an issue with time units to me. Ensure that you're converting to milliseconds correctly.
The easiest way to do this is to use Java's TimeUnit.
Timer cleaner = new Timer(true);
cleaner.scheduleAtFixedRate(new MyTimerTask(),
TimeUnit.SECONDS.toMillis(10),
TimeUnit.SECONDS.toMillis(30));
It could also be caused by the Timer being started in daemon mode. If all your main method does is set up the timer and then return the timer will never execute since it's the last remaining thread and because it's a daemon thread the JVM will exit.
To fix this either make the timer thread not a daemon (i.e. pass false in the constructor) or make the main thread wait for user input before exiting.
Here's an example using both of the above:
public class TimerDemo extends TimerTask {
public void run() {
System.out.printf("Time is now %s%n", LocalTime.now());
}
public static void main(String[] args) throws IOException {
Timer timer = new Timer(true);
timer.scheduleAtFixedRate(new TimerDemo(),
TimeUnit.SECONDS.toMillis(5),
TimeUnit.SECONDS.toMillis(10));
System.out.printf("Program started at %s%n", LocalTime.now());
System.out.println("Press enter to exit");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
// Wait for user to press enter
reader.readLine();
}
System.out.println("Bye!");
}
}
And output of running it:
Program started at 14:49:42.207
Press enter to exit
Time is now 14:49:46.800
Time is now 14:49:56.799
Time is now 14:50:06.799
Time is now 14:50:16.799
Time is now 14:50:26.799
[I pressed 'enter']
Bye!
Process finished with exit code 0
I had a hard time figuring out exactly what is your problem, so this might not be exactly what you are asking for, but this solution might fit you:
public class MyTimerTask implements Runnable {
private static final TimeUnit timeUnit = TimeUnit.SECONDS;
private final ScheduledExecutorService scheduler;
private final int period = 10;
public static void main(String[] args) {
new MyTimerTask();
}
public MyTimerTask() {
scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(this, period, period, timeUnit);
}
#Override
public void run() {
// This will run every 10 seconds
System.out.println("Ran...");
}
}
I want to do some timing tasks using ScheduledExecutorService, but time intervals are changeable. I try to reschedule a task before it finished:
import java.io.IOException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Test {
public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
public static int interval = 1;
public static void main(String[] args) throws IOException {
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println(System.currentTimeMillis() / 1000);
interval += 1;
scheduledExecutorService.schedule(this, interval, TimeUnit.SECONDS);
}
};
scheduledExecutorService.schedule(runnable, interval, TimeUnit.SECONDS);
}
}
But, I never found anyone do timing tasks using ScheduledExecutorService like this, I wonder whether it's safe.
As long as you use the method schedule that executes the task only once, there is nothing wrong with this approach, it will only re-schedule at each iteration the same task with a different delay. For the scheduler it will be seen as a new task scheduled at each iteration, nothing more.
I want schedule one java program to run at 15th,25th and 45th min of time every hour. For example:
17:15 , 17:25 , 17:45 , 18:15 and so on...
How can I acheive this using ScheduledExecutorService. I can see several examples which can trigger scripts after certain time intervals with respect to the time they are triggered using ScheduledExecutorService.
Can anyone suggest me relevent links and examples to get some idea
I could not find a way to schedule a Timer with uneven intervals. However, it is relatively straightforward to schedule a Timer to execute at fixed intervals.
For your case, you could schedule three timers, one for :15, one for :25, and one for :45 past the hour:
public class TaskTest {
public static scheduleTask(int interval) {
GregorianCalendar cal = new GregorianCalendar();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH);
int date = cal.get(Calendar.DATE);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int hourScheduled = hour;
// if we are past the scheduled time then schedule for the next hour
if (minute > interval) {
++hourScheduled;
}
cal.set(year, month, date, hourScheduled, interval);
long initialDelay = cal.getTimeInMillis() - System.currentTimeMillis();
if (initialDelay < 0) {
initialDelay = 0L;
}
// schedule each job for once per hour
int period = 60*60*1000;
Timer timer = new Timer();
SomeTask someTask = new SomeTask();
timer.scheduleAtFixedRate(someTask, initialDelay, period);
}
public static void main(String[] args) {
// schedule for the 15th, 25th and 45th min of time every hour
scheduleTask(15);
scheduleTask(25);
scheduleTask(45);
}
}
public class SomeTask extends TimerTask {
#Override
public void run() {
// do something
}
}
You want to trigger your code at some time point, not periodically, I think there are several choices:
if your program run under Linux or other systems which support crontab, then crontab is a good choice.
We could create multi cron job to achieve your target:
use command "crontab -e" to edit cron jobs:
15 * * * * /java_path/java your_program parameters
25 * * * * /java_path/java your_program parameters
35 * * * * /java_path/java your_program parameters
45 * * * * /java_path/java your_program parameters
if you don't want to use crontab, and you just want a pure java solution, quartz will help you.
quartz could let you configure cron triggers which are little like crontab under Linux.
please refer to http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-06.html to get more information.
At last, you want a pure java, and lightweight solution, you could simply use Java Timer and TimerTask, such as:
public class App {
public static void main(String[] args) {
Timer timer = new Timer();
TimerTask tt = new SchedulerTask();
DateFormat df = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
Date triggerTime = null;
try {
triggerTime = df.parse("2016-04-12 13:15:00");
} catch (ParseException e) {
e.printStackTrace();
}
timer.schedule(tt, triggerTime, 3600*1000);
}
static class SchedulerTask extends TimerTask {
#Override
public void run() {
System.out.println("I am running at " + Calendar.getInstance().getTime());
}
}
}
you could create 4 tasks like the task above, trigger at 13:15, 13:25, 13:35, 13:45 and each task runs once for every hour.
You can schedule same runnable with fixed 1hour interval & delay should be variable based on current time.
Example current time 6:10 than delay for your first schedule will be 5min(6:15), for second schedule 5+10=15 min(6:25).
like that you can create multiple schedule each with one hour delays.
import java.util.GregorianCalendar;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class MultipleScheduler {
public static void main(String[] args) {
Runnable task = new Runnable() {
#Override
public void run() {
System.out.println(System.currentTimeMillis() + " Task executed");
}
};
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
int BaseDelay = getInitialDelay();
service.scheduleAtFixedRate(task, BaseDelay, 60, TimeUnit.MINUTES);
service.scheduleAtFixedRate(task, BaseDelay + 10, 60, TimeUnit.MINUTES);
service.scheduleAtFixedRate(task, BaseDelay + 30, 60, TimeUnit.MINUTES);
}
static int getInitialDelay() {
GregorianCalendar cal = new GregorianCalendar();
int minute=cal.get(cal.MINUTE);
int delay=0;
//some logic to calculate delay updated delay should be returned
return delay;
}
}
I have to run a job using a thread for every 1 hour. This job is to read files in a folder. I have created a simple thread
Thread t = new Thread() {
#Override
public void run() {
while(true) {
try {
Thread.sleep(1000*60*60);
//Implementation
} catch (InterruptedException ie) {
}
}
}
};
t.start();
which runs every one hour so that I can call the function to read the files. I want to know if this approach is good or any other approach is good
You can use ScheduledExecutorService for this task, and here is a Sample Example
If you want to use just Thread then try
try {
Thread.sleep(1000 * 60 * 60);
} catch (InterruptedException ex) {}
otherwise its a good choice that you can go with ScheduledExecutorService
ScheduledExecutorService executor = ...
executor.scheduleAtFixedRate(someTask, 0, 1, TimeUnit.HOUR);
import java.util.Timer;
import java.util.TimerTask;
public class MyTimer {
public static void main(String[] args) {
OneHourJob hourJob = new OneHourJob();
Timer timer = new Timer();
timer.scheduleAtFixedRate(hourJob, 0, 5000 * 60 * 60); // this code
// runs every 5 seconds to make it one hour use this value 5000 * 60 *
// 60
}
}
class OneHourJob extends TimerTask {
#Override
public void run() {
System.out.println("Ran after one hour.");
}
}
Above code runs every five seconds. Whatever work you need to do write that code in run method of OneHourJob
I was wondering if someone might be able to see what I had done wrong here. I am trying to create a timer which will increment the count variable by 1 every second and print it out on the console. However, it prints the first number and then stops and I am not sure what is going on.
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest {
private Timer timer;
public int count = 0;
public TimerTest() {
timer = new Timer();
timer.schedule(new TimerListener(), 1000);
}
private class TimerListener extends TimerTask {
#Override
public void run() {
count++;
System.out.println(count);
}
}
public static void main(String[] args) {
new TimerTest();
}
}
I did find some other questions like this but none of their solutions made any difference to the result.
Thanks.
Your scheduling only runs the task once. You need to add a parameter to use the method schedule(TimerTask task,
long delay,
long period):
timer.schedule(new TimerListener(), 1000, 1000);