Does scheduling a java.util.timer exit that timer's timerTask method? - java

Suppose I have a class that looks something like this:
import javax.swing.*;
import java.util.*;
public class MyClass extends JFrame
{
private java.util.Timer timer = new java.util.Timer();
...
private class MyTimerTask extends TimerTask
{
#Override
public void run()
{
doStuff();
if (conditionIsMet())
{
timer.schedule(new MyTimerTask(), 1000);
}
else
{
timer.schedule(new MyTimerTask(), 500);
}
}
}
}
Now I have always thought of the run method of a TimerTask somewhat like a loop. It runs once, then, if you want to run it again you can do so by calling schedule. So my question is: When I call timer.schedule() does it execute any other code in the TimerTask or does it act as if I used break in a loop? If I wrote the method like this instead:
#Override
public void run()
{
doStuff();
if (conditionIsMet())
{
timer.schedule(new MyTimerTask(), 1000); // method wouldn't end after this call
}
timer.schedule(new MyTimerTask(), 500);
}
Would it function the same?

Scheduling a timer task is just a method call; it does not cause the current execution of the timer task's run() method to end, so no, the two code examples do not function the same. It's better practice to use the first of your two code examples, scheduling the task only once in the run method.

Related

How to submit a TimerTask to another Timer when it 's running

In a run method of a TimerTask object, How can I submit the timerTask itself to another Timer.
When the timerTask is running, I should do a judge and decide whether it can do some work. If it not meet the condition, I should cancel it and put it to another Timer.
Code of my TimerTask is like this:
#Override
public void run() {
try {
if (flag) {
// do something
} else {
new Timer().schedule(this, 1000 * 60);
}
} catch (Exception e) {
e.printStackTrace();
}
Will it work?
You should only use one Timer and then monitor the condition from external, for example from a Thread, a Runnable or another Timer. Then stop, cancel, re-assign, start the timer as necessary from your external monitor.
Here's a TimerTask:
public class OurTask extends TimerTask {
#Override
public void run() {
// Do something
}
}
And here's the monitor:
public Monitor implements Runnable() {
private Timer mTimerToMonitor;
public Monitor(Timer timerToMonitor) {
this.mTimerToMonitor = timerToMonitor;
}
#Override
public void run() {
while (true) {
if (!flag) {
// Cancel the timer and start a new
this.mTimerToMonitor.cancel();
this.mTimerToMonitor = new Timer();
this.mTimerToMonitor.schedule(...);
}
// Wait a second
Thread.sleep(1000);
}
}
}
Note that in practice your Monitor should also be able to get canceled from outside, currently it runs infinitely.
And this is how you could call it:
Timer timer = new Timer();
timer.schedule(new OurTask(), ...);
Thread monitorThread = new Thread(new Monitor(timer));
monitorThread.start();
Also note that instead of using Runnable, Timer and Thread it could be worth taking a look into the new Java 8 stuff, especially the interface Future and classes implementing it.

How to set a delay on a method

When i currently call my method
public void flip() {
Image change = new ImageIcon(this.getClass().getResource(imageName[0])).getImage();
ImageIcon card = new ImageIcon(change);
imagelbl.setIcon(card);
}
Currently when the method is called the code runs and the method works. This is perfect however i need there to be a delay of 1 second before the method runs.
I have tried using setTimeout() but i was unsuccessful. How would i get this method to have a 1 sec delay before running?
Use the Timer class for timing.
public void callerMethod() {
System.out.println("Start");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
delayedMethod();
}
}, 1000);
}
public void delayedMethod() {
System.out.println("Test");
}
Use Thread.sleep(1000) as the first line in flip() method.

How to stop a timer in java

I have a method called timer that I run everytime a user inputs something and the timer is scheduled for a minute, but I want the timer to cancel if the user enters something in less than a minute and then recall itself so the whole process happens again. My methods are below:
Input method
public static String run(){
timer(); //runs everytime I call run()
String s = input.nextLine();
return s;
}
Timer method
public static void timer() {
TimerTask task = new TimerTask() {
public void run() {
System.out.println("Times up");
}
};
long delay = TimeUnit.MINUTES.toMillis(1);
Timer t = new Timer();
t.schedule(task, delay);
}
method run() keeps getting called everytime someone inputs something so timer keeps getting called but that doesn't stop the previous timers though, I want the timer to stop, then recall itself so that problem doesn't exist. Anyone know a way?
The TimerTask class has a method called cancel() which you can call to cancel a pending timer.
In your code, you will probably need to modify your timer() function to return a reference to the newly created TimerTask object, so that you can later call cancel().

Timer Task Only Runs Once

How do I make my Timer Task run more than once? This is really bothering me..
timer = new Timer();
timer.schedule(new Client(), 1000);
public void run() {
try {
System.out.println("sent data");
socketOut.write(0);
} catch (Exception e) {
// disconnect client on their side
Game.destroyGame();
timer.cancel();
timer.purge();
}
}
I want this timer to run for an infinite amount of time until the Exception occurs.
When the Javadoc says that it repeats with a specific delay, the delay is the initial delay before the TimerTask starts and not for how long the TimerTask will run. You can repeat the task every period milliseconds. Look at the schedule method. Below is a simple example that repeats every 2 seconds, indefinitely. In the example, the call:
timer.schedule(new RemindTask(seconds), 0, seconds * 1000);
tells timer to run the RemindTask every seconds seconds (*1000 because the time here is really in miliseconds), with an initial delay of 0 - i.e. start the RemindTask right away and then keep repeating at regular intervals.
import java.util.Timer;
import java.util.TimerTask;
public class Main {
static Timer timer;
static int i = 0;
class RemindTask extends TimerTask {
private int seconds;
public RemindTask(int seconds) {
this.seconds = seconds;
}
public void run() {
i+= seconds ;
System.out.println(i + " seconds!");
}
}
public Main(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(seconds), 0, seconds * 1000);
}
public static void main(String args[]) {
new Main(2);
System.out.format("Task scheduled.%n");
}
}
Looks like to me you're running a GUI program (I'm assuimg SWING, because your other question you were using SWING). So here's a bit of advice. Use a javax.swing.Timer for Swing program.
"How do I make my Timer Task run more than once? "
javax.swing.Timer has methods .stop() and .start() and .restart(). A basic implementation of the Timer object is something like this
Timer timer = new Timer(delay, new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// do something
}
});
timer.start();
You can do anything you want in the actionPerformed and it will fire an event every how many ever milliseconds you provide to the delay. You can have a button call .start() or .stop()
See this answer for a simple implementation of Timer imitating a sort of stop watch for a Boggle game

Blackberry timer not firing TimerTask

I am trying to use a time that updates a label every second (so it shows a countdown) but it only
appears to be "ticking" once and I can't work out what I'm doing wrong!
public class Puzzle extends UiApplication {
public static void main(String[] args) {
Puzzle puzzle = new Puzzle();
puzzle.enterEventDispatcher();
}
public Puzzle() {
pushScreen(new PuzzleScreen());
}
}
class PuzzleScreen extends MainScreen {
LabelField timerLabel;
Timer timer;
public static int COUNT = 0;
public PuzzleScreen() {
//set up puzzle
VerticalFieldManager vfm = new VerticalFieldManager();
add(vfm);
timerLabel = new LabelField();
timerLabel.setText("00:20");
vfm.add(timerLabel);
StartTimer();
}
void StartTimer() {
timer = new Timer();
timer.schedule(new TimerTick(), 1000);
}
private class TimerTick extends TimerTask {
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
timerLabel.setText((COUNT++) + "");
}
});
}
}
Can anyone see what I am doing wrong..? All that happens is my label get's set to "0" and then doesn't change. I have put a breakpoint on the run in the timer tick class but I don't see it firing!
Bex
You'll need to change your Timer's schedule() call to
timer.schedule(new TimerTick(), 0, 1000);
The way you're calling it right now is saying to run it once after a second delay. This way says to run it now and every second. You probably want to use
timer.scheduleAtFixedRate(new TimerTick(), 0, 1000);
though, because it will make sure that on average your TimerTask is ran every second rather than with a normal schedule() call that says it will try waiting a second then executing, but it could fall behind if something slows it down. If scheduleAtFixedRate() is delayed, it will make multiple calls quicker than on the 1 second delay so it can "catch up." Take a look at http://www.blackberry.com/developers/docs/5.0.0api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask,%20long,%20long) for a more detailed explanation.

Categories

Resources