what is the main difference b/t ScheduledThreadPoolExecutor vs java.util.Timer vs javax.management.timer.Timer? what is advantage of one over the another? What is the best design for scheduling two jobs to run daily starting right after the server comes up?
One example i've seen had extended and attached NotificationListener with the JMX Timer.
public class TestNotificationListener implements NotificationListener {
javax.management.timer.Timer timer = new Timer();
public void init() {
Calendar calendar = Calendar.getInstance();
Date date1 = calendar.getTime();
Date date2 = calendar.getTime();
timer.addNotificationListener(this, null, "some handback object");
int job1Id = timer.addNotification("type1", "Order", this, date1, 10000);
int job2Id = timer.addNotification("type2", "Inventory ", this, date2, 10000);
timer.start();
}
public void handleNotification(Notification notif, Object handback) {
...
}
}
another example use the Timer directly...
public class TestNotificationListener extends ApplicationLifecycleListener {
public void postStart(final ApplicationLifecycleEvent evt) {
java.util.Timer Timer1 = new Timer();
Timer1.schedule(new Task1(), 10000);
java.util.Timer Timer2 = new Timer();
final SocialMediaCachingTask smcCacheTask = new SocialMediaCachingTask();
Timer2.schedule(new Task2(), 10000);
}
}
and finally i've seen the use of ScheduledThreadPoolExecutor
public class TestNotificationListener extends ApplicationLifecycleListener {
public void postStart(final ApplicationLifecycleEvent evt) {
Scheduler = new ScheduledThreadPoolExecutor(1);
Scheduler.schedule(new Task1(Scheduler), 10000, TimeUnit.SECONDS);
Scheduler2 = new ScheduledThreadPoolExecutor(1);
Scheduler2.schedule(new Task2(Scheduler2), 10000, TimeUnit.SECONDS);
}
}
Related
I want to run a function every hour, to email users a hourly screenshot of their progress. I code set up to do so in a function called sendScreenshot()
How can I run this timer in the background to call the function sendScreenshot() every hour, while the rest of the program is running?
Here is my code:
public int onLoop() throws Exception{
if(getLocalPlayer().getHealth() == 0){
playerHasDied();
}
return Calculations.random(200, 300);
}
public void sendScreenShot() throws Exception{
Robot robot = new Robot();
BufferedImage screenshot = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
screenshotNumber = getNewestScreenshot();
fileName = new File("C:/Users/%username%/Dreambot/Screenshots/Screenshot" + screenshotNumber +".");
ImageIO.write(screenshot, "JPEG", fileName);
mail.setSubject("Your hourly progress on account " + accName);
mail.setBody("Here is your hourly progress report on account " + accName +". Progress is attached in this mail.");
mail.addAttachment(fileName.toString());
mail.setTo(reciepents);
mail.send();
}
Use a ScheduledExecutorService:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
sendScreenShot();
}
}, 0, 1, TimeUnit.HOURS);
Prefer using a ScheduledExecutorService over Timer:
Java Timer vs ExecutorService?
According to this article by Oracle, it's also possible to use the #Schedule annotation:
#Schedule(hour = "*")
public void doSomething() {
System.out.println("hello world");
}
For example, seconds and minutes can have values 0-59, hours 0-23, months 1-12.
Further options are also described there.
java's Timer works fine here.
http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
// ...
}
}, delay, 1 * 3600 * 1000); // 1 hour between calls
For this type of period execution, meaning every day or every hour, all you need is using a Timer like this :
public static void main(String[] args) throws InterruptedException {
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 7);
today.set(Calendar.MINUTE, 45);
today.set(Calendar.SECOND, 0);
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("I am the timer");
}
};
// timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); // period: 1 day
timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS)); // period: 5 seconds
}
this exemple will execute the timetask every 5 seconds from the current date and 7:45 am.
Good Luck.
while (true) {
DateTime d = new DateTime();
switch(d.getMinuteOfHour()) {
case 56:
runHourly();
break;
case 41:
if(d.getHourOfDay() == 2) {
runAt0241Daily();
}
break;
}
SUM.wait(59000);
}
How about this for something you can control and understand?
We want to schedule a java process to run till a specific time interval. Currently I am thinking to using TimerTask to schedule this process. In the start of every loop, will check the current time and then compare with the given time and stop the process if the time is elapsed.
Our code is something like below:
import java.util.Timer;
import java.util.TimerTask;
public class Scheduler extends TimerTask{
public void run(){
//compare with a given time, with getCurrentTime , and do a System.exit(0);
System.out.println("Output");
}
public static void main(String[] args) {
Scheduler scheduler = new Scheduler();
Timer timer = new Timer();
timer.scheduleAtFixedRate(scheduler, 0, 1000);
}
}
Is there a better approach for this?
Instead of checking if the time limit has been reached in every single iteration you could schedule another task for the said time limit and call cancel on your timer.
Depending on the complexity you might consider using a ScheduledExecutorService such as ScheduledThreadPoolExecutor. See in this answer when and why.
Simple working example with timer:
public class App {
public static void main(String[] args) {
final Timer timer = new Timer();
Timer stopTaskTimer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("Output");
}
};
TimerTask stopTask = new TimerTask() {
#Override
public void run() {
timer.cancel();
}
};
//schedule your repetitive task
timer.scheduleAtFixedRate(task, 0, 1000);
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse("2015-06-09 14:06:30");
//schedule when to stop it
stopTaskTimer.schedule(stopTask, date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
You can use RxJava, a very powerful library for reactive programming.
Observable t = Observable.timer(0, 1000, TimeUnit.MILLISECONDS);
t.subscribe(new Action1() {
#Override
public void call(Object o) {
System.out.println("Hi "+o);
}
}
) ;
try {
Thread.sleep(10000);
}catch(Exception e){ }
You can even use the lambda syntax:
Observable t = Observable.timer(0, 1000, TimeUnit.MILLISECONDS);
t.forEach(it -> System.out.println("Hi " + it));
try {
Thread.sleep(10000);
}catch(Exception e){ }
I have a java function which is being called every x seconds in my program. i have wrapped my application with YAJSW. My question is: will the wrapper be able to stop the application even if the timer inside the programm is still running?! what is the way to stop the timer from outside the program? any idea other than reading from a file will be appreciated.
public static void main(String[] args) {
timer = new Timer();
long Delay = 5000;
TimerTask task = new TimerTask() {
#Override
public void run() {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
String dateStr = dateFormat.format(date);
}
};
timer.schedule(task, 0, Delay);
}
I am developing a system which has to start a task (download a file) regularly every N seconds. This is not a problem I did it using Timerand Timertaskas follows:
FileTimer rXMLFileTimer;
private static Timer timer = new Timer("FileReader");
rXMLFileTimer = new ReadFileTimer();
int myDelay = 30;
timer.scheduleAtFixedRate(rXMLFileTimer, 0, myDelay * 1000);
and the timertask will run until rXMLFileTimer.cancel() is called. Up to now no problem.
Now, It has been required that this timertask should run until the rXMLFileTimer.cancel() is called or a given amount of time.
My first approach (which didn't work) was to implement a Futureas follows:
public class Test {
public static class MyJob implements Callable<ReadFileTimer> {
#Override
public ReadFileTimer call() throws Exception {
Timer timer = new Timer("test");
ReadFileTimer t = new ReadFileTimer();
int delay = 10;
// Delay in seconds
timer.schedule(t, 0, delay * 1000);
return t;
}
}
public static void main(String[] args) {
MyJob job = new MyJob();
System.out.println(new Date());
Future<ReadFileTimer> control = Executors.newSingleThreadExecutor().submit(job);
ReadFileTimer timerTask = null;
try {
int maxAmountOfTime = 30;
timerTask = control.get(maxAmountOfTime, TimeUnit.SECONDS);
} catch (TimeoutException ex) {
control.cancel(true);
} catch (InterruptedException ex) {
} catch (ExecutionException ex) {}
}
}
This is not working because I cannot call timerTask.cancel() after the timeout has happen. Then my question is: How can I start a timerTaskfor a given amount of time?
Thanks!
Why not just throw in a second timer task to cancel the first? For example, this code prints the date every second for ten seconds:
public static void main(String[] args) throws Exception {
Timer timer = new Timer();
final TimerTask runUntilCancelledTask = new TimerTask() {
#Override
public void run() {
System.out.println(new Date());
}
};
timer.schedule(runUntilCancelledTask, 0, 1000);
timer.schedule(new TimerTask() {
#Override
public void run() {
runUntilCancelledTask.cancel();
}
}, 10000); // Run once after delay to cancel the first task
}
I'm not an expert, just a beginner. So I kindly ask that you write some code for me.
If I have two classes, CLASS A and CLASS B, and inside CLASS B there is a function called funb(). I want to call this function from CLASS A every ten minutes.
You have already given me some ideas, however I didn't quite understand.
Can you post some example code, please?
Have a look at the ScheduledExecutorService:
Here is a class with a method that sets up a ScheduledExecutorService to beep every ten seconds for an hour:
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
final Runnable beeper = new Runnable() {
public void run() { System.out.println("beep"); }
};
final ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
scheduler.schedule(new Runnable() {
public void run() { beeperHandle.cancel(true); }
}, 60 * 60, SECONDS);
}
}
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class ClassExecutingTask {
long delay = 10 * 1000; // delay in milliseconds
LoopTask task = new LoopTask();
Timer timer = new Timer("TaskName");
public void start() {
timer.cancel();
timer = new Timer("TaskName");
Date executionDate = new Date(); // no params = now
timer.scheduleAtFixedRate(task, executionDate, delay);
}
private class LoopTask extends TimerTask {
public void run() {
System.out.println("This message will print every 10 seconds.");
}
}
public static void main(String[] args) {
ClassExecutingTask executingTask = new ClassExecutingTask();
executingTask.start();
}
}
Try this. It will repeat the run() function every set minutes. To change the set minutes, change the MINUTES variable
int MINUTES = 10; // The delay in minutes
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() { // Function runs every MINUTES minutes.
// Run the code you want here
CLASSB.funcb(); // If the function you wanted was static
}
}, 0, 1000 * 60 * MINUTES);
// 1000 milliseconds in a second * 60 per minute * the MINUTES variable.
Don't forget to do the imports!
import java.util.Timer;
import java.util.TimerTask;
For more info, go here:
http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html
http://docs.oracle.com/javase/7/docs/api/java/util/TimerTask.html
public class datetime {
public String CurrentDate() {
java.util.Date dt = new java.util.Date();
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTime = sdf.format(dt);
return currentTime;
}
public static void main(String[] args) {
class SayHello extends TimerTask {
datetime thisObj = new datetime();
public void run() {
String todaysdate = thisObj.CurrentDate();
System.out.println(todaysdate);
}
}
Timer timer = new Timer();
timer.schedule(new SayHello(), 0, 5000);
}
}
Solution with Java 8
ClassB b = new ClassB();
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
Runnable task = () -> {
b.funb();
};
executor.scheduleWithFixedDelay(task, 0, 10, TimeUnit.MINUTES);