tags:

views:

152

answers:

5

I'm writing an application in Java, but need to know how to subtract from a variable once every second. What's the easiest way to do this? Thanks!

A: 

Use a java.util.Timer to create a TimerTask.

Paul Tomblin
+6  A: 

The name of the very Java class you need to use to do repeating operations is already sitting there in one of your tags! ;)

Jonathan Feinberg
How amusing, and yet rude. I will look it up.
Nathan Lawrence
Sorry, no rudeness intended! Just trying to keep it loose.
Jonathan Feinberg
+1 nevertheless. I would have responsed the same way.
BalusC
Rude is a bit relative to culture. In my household or most of the online technical circles I'm in, this response would've gotten a laugh from everyone, including the questioner.
skiphoppy
What's funny is that I often do intend to be sharp, but not on this occasion... I guess I got stuck that way.
Jonathan Feinberg
Helpful answer, +1. I saw no rudeness.
Carl Smotricz
I didn't mean I didn't enjoy reading it!
Nathan Lawrence
+2  A: 
class YourTimer extends TimerTask
{
  public volatile int sharedVar = INITIAL_VALUE;

  public void run()
  {
    --sharedVar;
  }

  public static void main(String[] args)
  {
     Timer timer = new Timer();

     timer.schedule(new YourTimer(), 0, 1000);
     // second parameter is initial delay, third is period of execution in msec
  }
}

Remeber that Timer class is not guaranteed to be real-time (as almost everything in Java..)

Jack
You need to make the sharedVar volatile, since the timer runs in a different thread as the program that reads it.
hstoerr
Noone is reading it actually. However by a matter of principle that' s right.. it should be volatile because otherwise it can be cached by threads (losing synchronization)
Jack
Use `scheduleAtFixedRate()` rather than `schedule()` to overcome the "not real-time" problem.
BalusC
+5  A: 

While the Timer class will work, I recommend using a ScheduledExecutorService instead.

While their usage is extremely similar, ScheduledExecutorService is newer, more likely to receive ongoing maintenance, fits in nicely with other concurrent utilities, and might offer better performance.

erickson
It's nice to learn about the ScheduledExecutorService, for which +1. However, I'd ask to see evidence that the one is going to be better maintained than the other.
Jonathan Feinberg
+2  A: 

What are you trying to achieve? I would not try relying on the timer to properly fire exactly once per second. I would simply record the start time, and whenever a timer fires, recalculate what the value of the variable should be. Here's how I would do it...

class CountdownValue {
  private long startTime;
  private int startVal;

  public CountdownValue(int startVal)
  {
     startTime = System.currentTimeMillis();
  }

  public int getValue()
  {
     return startVal - (int)((System.currentTimeMillis() - startTime)/1000);
  }
}
Yuliy
There is no such method as `getCurrentTimeMillis()`. At any way, if you're trying to reinvent the `java.util.Timer`, rather use `nanoTime()` than `currentTimeMillis()` as it has much better accuracy.
BalusC
I'm not trying to reinvent the timer. I'm trying to get something that will work more reliably on a heavily loaded system (i.e. you won't have incorrect values for a few hundredths of a second while the timer is waiting for a timeslice).
Yuliy
Also, good catch on the getCurrentTimeMillis typo. fixed that.
Yuliy