Java: Keep executing if statement - java

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.

Related

Run method in Timer task is executing two times

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.

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
}

With each successive call to this `timerMethod` , timerInt's value increases faster than before

I am working on an app, which gets a sort of restart with an event. On the first run, the timer works perfect (1sec = 1 increment). but, on next run (1sec = 2 increment) on third run (1sec = 4 increment) and so on...
I think there is something wrong with the new TimerTask object being created. but, dunno how to handle it. any suggestion or alternate ?
CODE SNIPPET:
Timer t = new Timer();
void timerMethod()
{
t.schedule(new TimerTask() {
public void run() {
timerInt++;
//TODO bug in timer in consecutive runs. To confirm, see log
Log.d("timer", "timer " + timerInt);
/* runOnUiThread(new Runnable() {
#Override
public void run() {
timerDisplayPanel.setText( timerInt + " Sec");
}
});*/
}
}, 1000, 1000);
}
It sounds like you're calling timerMethod() multiple times.
When you've called it three times, you've got three timer tasks scheduled - so they'll all fire each second, and all increment timerInt. You either need to not call it multiple times, or cancel the existing timer tasks before adding more.
If that's not the case, please provide a short but complete program to show what's happening. The context is fairly vague at the moment.
The snippet you provided is working properly
1 sec 1 increment
2 sec 2 increment
3 sec 3 increment
etc
So probably the problem is somewhere else in your code.

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();
}
});
}
};

Timer Help:Working on a project for my AP Computer Science class

In our class we are making a game. The user has to Guess words and stuff. I don't think info about the game is needed to answer my question/problem.
Ok so what I am trying to do is to give the user a time limit in which they have to guess the word. Something like 15 seconds. If the user does not guess the word in 15 seconds they lose a turn.
Problems:
We didn't learn how to use timers. I experiment with timers and stuff. I can get a timer to count down from 15.
I can't check the current time while waiting for the user to input a guess.
I don't know how to bypass Stdin.readString() and make the program check the time.
Thanks.
Well, you can use the Scanner class to gather input from the user.
You may want to avoid timers if you don't know what threading is yet, but if you do want to try, you might be interested looking into the TimerTask & Timer classes.
While you may already know, you can get time from the System class, like currentTimeMillis
You have a few options. As you said, your program is waiting for input and hence that thread is busy. What you can do is create a separate thread, pass your timer to that thread and have it check the timer. Perhaps something like the following:
public class TimerChecker implements Runnable {
private Timer timer;
public TimerChecker(Timer timer) { this.timer = timer; }
#Override
public void run() {
// implement logic here
}
}
Which you can have invoked in a new thread using:
Timer timer = ...
new Thread(new TimerChecker(timer)).start();
// Now you are free to perform your blocking operation in the current thread
Stdin.readString();
One way to do this is, well to a run a separate thread object for the timer... this thread shall handle the updating of the time and would then trigger a certain event when the time of the player runs out...
or more like, implementing a counter in a separate thread whose increments are triggered by time-step, in this case, in seconds, you can do this by calling sleep()..
the timer thread object shall maintain a variable which keeps track of the current time..
on the main method of your program, you shall continue to check the value of this variable, as a pre-condition of your main loop perhaps,
the idea is there i think, just a thought!
pseudocode
class Timer extends Thread{
int current_time = 0;
public void run(){
sleep(1000);
current_time += 1;
}
public void synchronized getCurTime(){
return current_time;
}
}
class Game{
public Game(){
Timer timer = new Timer();
timer.start();
while (timer.getCurTime() <16){
//get the guess of the user
//checks if it's correct
// if it is correct, output you win and break!
}
//time runs out
}
}
How about an Event driven architecture with Java eventing library?
Example of events with conditions.

Categories

Resources