Run method in Timer task is executing two times - java

I have created a Timer which runs for every 20 seconds. Timer task is taking more than a minute to finish the task. Run method in Timer task is executing two times after 20 seconds before timer task is finished.
class A {
static Timer timer;
TimerTask timertask = new TimerTask({
public void run(){
if(check for some data in the database before inserting )
// Insert records into database
}
}
public test(){
A.timer.scheduleAtFixedRate(imertask,0, 20*1000);
}
}
Two records of the same data are inserted into the database with the time difference of 14 seconds. I am expecting only one record to be in the database Any help on this so much appreciated.

By intent, if the first execution takes more than 20 seconds, the second execution will start immediately after. If the first execution takes more than 40 seconds, the third execution will start immediately after the second execution. And so on until you catch up to having approximately N/20 executions after N seconds.
Documentation link
In fixed-rate execution, each execution is scheduled relative to the
scheduled execution time of the initial execution. If an execution is
delayed for any reason (such as garbage collection or other background
activity), two or more executions will occur in rapid succession to
"catch up." In the long run, the frequency of execution will be
exactly the reciprocal of the specified period (assuming the system
clock underlying Object.wait(long) is accurate).
If you're inserting the same data twice, then it seems that problem would be with however you decide whether you've already inserted that data, rather than with the interval between executions.
If the task runs for about a minute, is that indicative of a bug, or just how long it takes (for example to connect to a remote database)?

This worked fine
class A {
static Timer timer;
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
System.out.println("Task is running");
}
};
public void test() {
timer = new Timer();
timer.scheduleAtFixedRate(timerTask, 0, 5 * 1000);
}
public static void main(String[] args) {
A a = new A();
a.test();
}
}

I could not figure why Timer task is running concurrently. I have written same logic and scheduling using Thread and everything is working now.

Related

How to set the interval in milliseconds so that it will consistently change once every 100ms?

I want to make my millisecond time change every 100ms, but the time I get is inconsistent sometimes the intervals I get are 99, 100 and 101. The interval I want is 100 and consistent.
as below my problem is now the resulting interval will change like number 4 and 5.
19:56:16:096
19:56:16.196
19:56:16.296
19:56:16.397
19:56:16.495
while the result I want is like this below
19:56:16.096
19:56:16.196
19:56:16.296
19:56:16.396
19:56:16.496
here's a screenshot of my App
here's the code I use
public void startTimer(){
carousalTimer = new Timer(); // At this line a new Thread will be created
carousalTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//DO YOUR THINGS
runOnUiThread(new Runnable() {
#Override
public void run() {
long time = System.currentTimeMillis();
SimpleDateFormat sdf3 = new SimpleDateFormat("HH:mm:ss.SSS");
Date date = new Date();
data = sdf3.format(time).toString();
aList.add(data);
get(data);
}
});
}
}, 100, 100); // delay
}
I believe it is part of how Android works. It is a multi-threaded environment where resources are share among multiple processes.
According to the documentation Timer.scheduleAtFixedRate() is the best approach for the following use cases:
In fixed-rate execution, each execution is scheduled relative to the
scheduled execution time of the initial execution. If an execution is
delayed for any reason (such as garbage collection or other background
activity), two or more executions will occur in rapid succession to
"catch up." In the long run, the frequency of execution will be
exactly the reciprocal of the specified period (assuming the system
clock underlying Object.wait(long) is accurate).
Fixed-rate execution is appropriate for recurring activities that are
sensitive to absolute time, such as ringing a chime every hour on the
hour, or running scheduled maintenance every day at a particular time.
It is also appropriate for recurring activities where the total time
to perform a fixed number of executions is important, such as a
countdown timer that ticks once every second for ten seconds. Finally,
fixed-rate execution is appropriate for scheduling multiple repeating
timer tasks that must remain synchronized with respect to one another.
https://developer.android.com/reference/java/util/Timer#scheduleAtFixedRate
If it is only necessary to be visual perfect, you can set the time relative to the start time. For example by increment an index every 100ms:
final long DELAY = 100; // 100ms delay
AtomicInteger index = AtomicInteger(0);
long startTime = System.currentTimeMillis();
carousalTimer = new Timer(); // At this line a new Thread will be created
carousalTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
long time = startTime + (index.incrementAndGet() * DELAY)
SimpleDateFormat sdf3 = new SimpleDateFormat("HH:mm:ss.SSS");
Date date = new Date();
data = sdf3.format(time).toString();
aList.add(data);
get(data);
}
});
}
}, DELAY, DELAY);

Java Clock Synchronizing

I have to show multiple clocks in screen from different places like New Delhi, Hong Kong, Frankfurt, Washington, etc. And these times are changing like any other real clock but as Time-Left to a fixed date-time and they are added to the screen at different moments as the user adds them. For example:
New Delhi 1d 4h 20 min 5s
Hong Kong 9h 2min 55s
Washington 22min 3s
...
I have a Class which makes all the calculations to get those times in that format. The problem comes when these times are shown on screen. How do I make them to update their time at the same time? So all the changes in the seconds are shown at the same time. I know it won't be theoretically at the same time, but the most close to it. This is the timer I am using:
Timer t = new Timer();
t.scheduleAtFixedRate(
new TimerTask()
{
public void run() {
Platform.runLater(new Runnable() {
#Override
public void run() {
label[id].setText(getTimeLeft(id));
}
});
}
},
0, // run first occurrence immediately
1000); // run every seconds
Also, some of them freeze eventually. Does any body knows why?
How do I make them to update their time at the same time? So all the changes in the seconds are shown at the same time. I know it won't be theoretically at the same time, but the most close to it. This is the timer I am using:
Instead of using separate Timers for each label, use a single Timer for ALL the labels
Timer t = new Timer();
t.scheduleAtFixedRate(
new TimerTask()
{
public void run() {
Platform.runLater(new Runnable() {
#Override
public void run() {
for (int id = 0; id < label.length; id++) {
label[id].setText(getTimeLeft(id));
}
}
});
}
},
0, // run first occurrence immediately
1000); // run every seconds
This will reduce the overhead of resources on you system (one timer instead of n times), possible event queue spamming as multiple timers trigger simultaneously and allow the times to "seem" to update at the same time, as they are all updated within the event queue, so they won't update until the next paint cycle, which won't happen until you exit the run block...
You could also make use Timeline, which would reduce the need for Platform.runLater, see How to update the label box every 2 seconds in java fx? for an example.

JAVAFX, Countdown doesn't work

The count down does not work. I'm triggering it through a button.
public void startCountDown() {
timer.schedule(new TimerTask() {
#Override
public void run() {
Platform.runLater(new Runnable() {
public void run() {
countDown--;
countDownText.setText("Time left:" + countDown);
if (countDown < 0)
timer.cancel();
}
});
}
}, 1000); //Every 1 second
}
The countDown variable is set to 60, so the countdown starts at 60
EDIT: The countdown gets stuck at 59 seconds, countDown is an int. No errors. And countDownText is declared as text.
#FXML
private Text countDownText;
There's more than 1 timer class, but I assume you used java.util.Timer
Examining the API shows you used this method:
public void schedule(TimerTask task,
long delay)
Schedules the specified task for execution after the specified delay.
Parameters:
task - task to be scheduled.
delay - delay in milliseconds before task is to be executed.
Throws:
IllegalArgumentException - if delay is negative, or delay + System.currentTimeMillis() is negative.
IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
NullPointerException - if task is null
So your program waits 1 second then executes the run() method, but does not repeat. To make it repeat, you need to use this method:
public void schedule(TimerTask task,
long delay,
long period)
Schedules the specified task for repeated fixed-delay execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals separated by the specified period.
In fixed-delay execution, each execution is scheduled relative to the actual execution time of the previous execution. If an execution is delayed for any reason (such as garbage collection or other background activity), subsequent executions will be delayed as well. In the long run, the frequency of execution will generally be slightly lower than the reciprocal of the specified period (assuming the system clock underlying Object.wait(long) is accurate).
Fixed-delay execution is appropriate for recurring activities that require "smoothness." In other words, it is appropriate for activities where it is more important to keep the frequency accurate in the short run than in the long run. This includes most animation tasks, such as blinking a cursor at regular intervals. It also includes tasks wherein regular activity is performed in response to human input, such as automatically repeating a character as long as a key is held down.
Parameters:
task - task to be scheduled.
delay - delay in milliseconds before task is to be executed.
period - time in milliseconds between successive task executions.
Throws:
IllegalArgumentException - if delay < 0, or delay + System.currentTimeMillis() < 0, or period <= 0
IllegalStateException - if task was already scheduled or cancelled, timer was cancelled, or timer thread terminated.
NullPointerException - if task is null
You can view the complete documentation here: http://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#schedule%28java.util.TimerTask,%20long%29
Here is what I think is correct code:
public void startCountDown() {
timer.schedule(new TimerTask() {
#Override
public void run() {
Platform.runLater(new Runnable() {
public void run() {
countDown--;
countDownText.setText("Time left:" + countDown);
if (countDown < 0)
timer.cancel();
}
});
}
}, 1000, 1000); //Every 1 second
}

Java: Keep executing if statement

I have an if statement which evaluates the time since the program has begun running and if the time is above a certain threshold, does something. I want this if statement to be checked throughout the whole time the program is running while at the same time have the program continue execution. How would I go about doing this?
Thank you.
The easiest approach would be to use a Timer. With that, you don't need the if logic; you can just use the firstTime argument when scheduling a TimerTask.
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
// do something
}
};
// schedule the task to be run every 100ms (0.1 sec),
// starting after "threshold" milliseconds have past
timer.schedule(task, threshold, 100);
It's not clear from your description if you want to repeatedly "do something" once the time threshold has been exceeded, or if you just want to wait until a certain time has passed and then "do something" once. The above code is for the repeating case. For a one-shot occurrence at some future time, change the last line to:
timer.schedule(task, threshold);
If you're using Swing, you should use a Swing Timer rather than a java.util.Timer. See How to Use Swing Timers for more info.
EDIT: Your comment clarified things a bit. It's fairly easy to do what you described:
Timer timer = new Timer();
TimerTask task = new TimerTask() {
private final long start = System.currentTimeMillis();
#Override
public void run() {
if (System.currentTimeMillis() - start < threshold) {
// do something
} else {
// do something else
}
}
};
// schedule the task to be run every 100ms (0.1 sec), starting immediately
timer.schedule(task, 0, 100);
Note that "do something" and "do something else" can be method calls to an enclosing class.
A cleaner approach might be to define several TimerTasks that are scheduled to execute at different times. The "something else" task that triggers an exception can be scheduled for one-time execution at the threshold time. You can also cancel individual tasks and you can even schedule a task that will cancel another task.

Recurring Countdown Timer in Java

I'm trying to implement a countdown timer into a pre-existing public class and I have a few questions.
An overview: I want to have a timer within a program that counts down from 60 (seconds) once the program is initialized.
If the timer reaches zero, the program quits.
If the user meets certain parameters within the 60 second time frame, the timer resets to 60, presents a new set of parameters, and begins the countdown again. It should be able to do this an infinite number of times, until the user fails to meet parameters within 60 seconds.
There will also be some sort of (TBD) GUI representation of the timer, most likely either numerical countdown or JProgressBar.
I'm semi-new (~3 months) to programming, self-taught, and still learning lots (so be gentle) :)
My questions are:
What is the best way to implement this?
I'm assuming this needs to run in a thread?
Will the timer be easily configurable? (not important, just interesting)
Thanks for your help. If you need to see code, I can find some.
EDIT: Just for some clarification/context:
This is for a timed racing video game I'm working on to develop my skills as a programmer. The idea is that a player has 60 seconds to complete a lap. If the player completes a successful lap, the timer resets to 60 seconds and the track changes to be slightly more difficult. The game runs until the player is unable to complete a lap in 60 seconds due to the difficulty. The game records the number of laps as a high score, and asks to player if they would like to try again.
If I were you, I'd use:
an AtomicInteger variable which would keep the current countdown value;
a timer thread that would wake up every 1s and decrementAndGet() the variable, comparing the result to zero and terminating the app if the result is zero;
(possibly) a thread that would also wake up every 1s to repaint the GUI -- the best approach here depends on your GUI framework.
Finally, whenever you need to reset the count back to 60s, you just call set(newValue) from any thread.
The timer thread's run() method could be as simple as:
for (;;) {
if (counter.decrementAndGet() <= 0) {
// TODO: exit the app
}
Thread.sleep(1000);
}
I think it's much easier to get this right than trying to manage multiple Timer objects.
The best way to impliment timer in your application is using some sheduler frameworks like Quartz
You could use java.util.Timer to schedule an execution of a method and then cancel it if the requirements is met.
Like this:
timer = new Timer();
timer.schedule(new Task(), 60 * 1000);
And then make a class like this to handle the timerschedule:
class Task extends TimerTask {
public void run() {
System.exit(0);
}
}
If the requirements is met, then do this to stop it from executing:
timer.cancel();
If you need to update your GUI better to use SwingWorker http://en.wikipedia.org/wiki/SwingWorker
I would write something like this:
SwingWorker<String, Integer> timer = new SwingWorker<String, Integer>() {
Integer timer=60;
#Override
protected String doInBackground() throws Exception {
//update guiModel
//label.setText(timer.toString());
while(timer>0){
Thread.sleep(1000);
timer--;
}
return null;
}
#Override
public void done(){
System.exit(0);
}
};
JButton restart = new JButton(){
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
timer.cancel(true);
timer.execute();
}
});
}
};

Categories

Resources