0

I know this may be completely obvious for more experenced programmers but I can't find anything on it.

I need to make a thread that "ticks" at a constant amount of times per second no matter how long the task it has to execute is. A task that takes longer than each tick would obviously not be possible and slow the number of ticks per second.

Thanks.

user2248702
  • 2,741
  • 7
  • 41
  • 69

3 Answers3

3

Use java.util.Timer.scheduleAtFixedRate:

public void scheduleAtFixedRate(TimerTask task,
                       Date firstTime,
                       long period)

Schedules the specified task for repeated fixed-rate execution, beginning at the specified time. Subsequent executions take place at approximately regular intervals, separated by the specified period.

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). As a consequence of the above, if the scheduled first time is in the past, then any "missed" executions will be scheduled for immediate "catch up" execution.

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.

Community
  • 1
  • 1
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
1

Here is a Thread version. A Timer would be the way to go but if you really want to use your own thread.

new Thread(new Runnable() {

    @Override
    public void run() {
        try {
        long before, sleepDuration, operationTime;
        for(int i=0;i<100;i++) {
            before = System.currentTimeMillis();
            // do your operations
            operationTime = (long)(1500*Math.random());
            System.out.print("Doing operations for "+operationTime+"ms\t");
            Thread.sleep(operationTime);

            // sleep for up to 1000ms
            sleepDuration = Math.min(1000, Math.max(1000 - (System.currentTimeMillis() - before), 0));
            Thread.sleep(sleepDuration);
            System.out.println("wait\t"+sleepDuration+"ms =\telapsed " + (operationTime+sleepDuration) + (operationTime > 1000 ? "<" : ""));
        }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}).start();
ug_
  • 11,267
  • 2
  • 35
  • 52
  • What would happen to the Timer and the thread version if the system time was to change? –  Jan 10 '14 at 02:21
  • @Chris take a look at the last paragraph of this question. http://stackoverflow.com/questions/1453295/timer-timertask-versus-thread-sleep-in-java – ug_ Jan 10 '14 at 02:22
  • If this were to be used for executing a complex algorithm every second which had to be executed every second and the time changed that would be a huge problem and as nothing would happen for an hour. –  Jan 10 '14 at 02:34
  • Yes well I suppose if your running a heart monitor don't change the system time... Or use a thread that will only ever sleep for a maximum 1s – ug_ Jan 10 '14 at 02:37
  • I may be clutching at straws here but is there a possibility of running a separate thread that notifies the thread that actual function in every second, therefore if the time changes it still has a consistant tick from the other thread? –  Jan 10 '14 at 02:41
  • @Chris The example I gave does not have that problem, the thread will be +-1 second at worst. Plus what in the world are you doing on a normal computer that would require that kind of precision?! If you need that kind of precision then your executing in the wrong environment. – ug_ Jan 10 '14 at 02:49
0

The Timer and TimerTask classes are perfect for your use.

Take a look at the docs http://docs.oracle.com/javase/6/docs/api/index.html?java/util/Timer.html or follow this lesson http://enos.itcollege.ee/~jpoial/docs/tutorial/essential/threads/timer.html

Let me know if I misunderstood your question.

Akshay
  • 3,158
  • 24
  • 28