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);
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){ }
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);
}
}
Please have a look at the following code
public class Test {
public Test()
{
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run()
{
System.out.println("Updated");
}
}, System.currentTimeMillis(),1000);
}
public static void main(String[]args)
{
new Test();
}
}
In here, you can see it is not printing anything! In other words, the time is not scheduled! Why is that? I want to schedule the task to happen in every second. Please help!
You are telling the Timer to wait (approximately) 1363531420 milliseconds before executing your TimerTask. This works out to ~42 years. You should be using Timer.schedule(yourTask, 0, 1000).
Try to execute this code:
import java.util.Timer;
import java.util.TimerTask;
public class Test {
public Test()
{
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run()
{
System.out.println("Updated");
}
}, 0,1000);
}
public static void main(String[]args)
{
new Test();
}
}
Take a look at the javadoc, there are two methods:
schedule(TimerTask task, Date firstTime, long period)
schedule(TimerTask task, long delay, long period)
You are passing in (TimerTask, long, long) and are therefore invoking the second one - i.e. schedule the task to run for the first time in System.currentTimeMillis() millis and every second thereafter. So your task will run for the first time at Thu Jun 01 06:45:28 BST 2056, to find that out:
public static void main(String[] args) {
System.out.println(new Date(2*System.currentTimeMillis()));
}
You need to invoke the method with zero:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("Updated");
}
}, 0, 1000);
This means schedule the task to run for the first time in zero millis and every second thereafter.
You have set the delay to the current time in millis (which would be a very long time :) ). You probably intended this:
public class Test {
public Test()
{
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run()
{
System.out.println("Updated");
}
}, new Date(System.currentTimeMillis()),1000); //<--- Notice a date is being constructed
}
public static void main(String[]args)
{
new Test();
}
}
Where you set the firstTime to the current date.
How can I change period of Timer at runtime?
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
// read new period
period = getPeriod();
doSomething();
}
}, 0, period);
You cannot do this directly, but you can cancel the tasks on the Timer and reschedule them with the desired period.
There is no getPeriod method.
You can do it like this:
private int period= 1000; // ms
private void startTimer() {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
// do something...
System.out.println("period = " + period);
period = 500; // change the period time
timer.cancel(); // cancel time
startTimer(); // start the time again with a new period time
}
}, 0, period);
}
You can use the following class to change the execution period of a TimerTask at runtime.
As already explained, it can not really change the period but has to cancel and reschedule the task:
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.function.Supplier;
/**
* {#link TimerTask} with modifiable execution period.
*
* #author Datz
*/
public class EditablePeriodTimerTask extends TimerTask {
private Runnable task;
private Supplier<Long> period;
private Long oldP;
/**
* Constructor with task and supplier for period
*
* #param task the task to execute in {#link TimerTask#run()}
* #param period a provider for the period between task executions
*/
public EditablePeriodTimerTask(Runnable task, Supplier<Long> period) {
super();
Objects.requireNonNull(task);
Objects.requireNonNull(period);
this.task = task;
this.period = period;
}
private EditablePeriodTimerTask(Runnable task, Supplier<Long> period, Long oldP) {
this(task, period);
this.oldP = oldP;
}
public final void updateTimer() {
Long p = period.get();
Objects.requireNonNull(p);
if (oldP == null || !oldP.equals(p)) {
System.out.println(String.format("Period set to: %d s", p / 1000));
cancel();
new Timer().schedule(new EditablePeriodTimerTask(task, period, p), p, p);
// new Timer().scheduleAtFixedRate(new EditablePeriodTimerTask(task, period), p, p);
}
}
#Override
public void run() {
task.run();
updateTimer();
}
}
The Timer can bes started like this:
EditablePeriodTimerTask editableTimerTask =
new EditablePeriodTimerTask(runnable, () -> getPeriod());
editableTimerTask.updateTimer();
Where runnable is your real task to be executed and getPeriod() provides the period between the task executions. Which of course can change depending on your requirements.
Timer timer = new Timer(); //should not create timer again
private long periord = 1000; // periord is changed at runtime
public void runTaskPeriord() {
TimerTask task = new TimerTask() {
#Override
public void run() {
log.debug("Task run" );
if(periord <= 3000) {
this.cancel(); // cancel this task to run new task
periord += 1000;
runTaskPeriord();
}
}
};
timer.schedule(task, periord, periord);
int countDeletedTasks = timer.purge(); // remove cancel task from timer
}