Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You'd need a <a href="http://download.oracle.com/javase/7/docs/api/java/util/Timer.html" rel="nofollow">Timer</a>. Take a look at its methods... There's a number of them, but they can be divided into two categories: those that schedule at a fixed delay (the <code>schedule(...</code> methods) and those that schedule at a fixed rate (the <code>scheduleAtFixedRate(...</code> methods).</p> <p>A fixed delay is what you want if you require "smoothness". That means, the time in between executions of the task is mostly constant. This would be the sort of thing you'd require for an animation in a game, where it's okay if one execution might lag behind a bit as long as the average delay is around your target time.</p> <p>A fixed rate is what you want if you require the task's executions to amount to a total time. In other words, the average time over all executions must be constant. If some executions are delayed, multiple ones can then be run afterwards to "catch up". This is different from fixed delay where a task won't be run sooner just because one might have "missed" its cue.</p> <p>I'd reckon fixed rate is what you're after. So you'd need to create a new <code>Timer</code> first. Then you'd need to call method <code>scheduleAtFixedRate(TimerTask task, long delay, long period)</code>. That second argument can be 0 if you wish the timer to start immediately. The third argument should be the time in between task runs. In your case, if you want the total time to be 1000 milliseconds, it'd be 1000/array size. Not array size/1000 as you did.</p> <p>That leaves us with the first argument: a <a href="http://download.oracle.com/javase/7/docs/api/java/util/TimerTask.html" rel="nofollow">TimerTask</a>. Notice that this is an abstract class, which requires only the <code>run()</code> method to be implemented. So you'll need to make a subclass and implement that method. Since you're operating over an array, you'll need to supply that array to your implementation, via a constructor. You could then keep an index of which element was last processed and increment that each time <code>run()</code> is called. Basically, you're replacing the for loop by a <code>run()</code> method with a counter. Obviously, you should no longer do anything if the counter has reached the last element. In that case, you can set some (boolean) flag in your TimerTask implementation that indicates the last element was processed.</p> <p>After creating your TimerTask and scheduling it on a Timer, you'll need to wait for the TimerTask's flag to be set, indicating it has done its work. Then you can call <code>cancel()</code> on the Timer to stop it. Otherwise it's gonna keep calling useless <code>run()</code> methods on the task.</p> <p>Do keep the following in mind: if the work done in the <code>run()</code> method typically takes longer than the interval between two executions, which in your case would be around 2 milliseconds, this isn't gonna work very well. It only makes sense to do this if the for loop would normally take less than 1 second to complete. Preferably much less.</p> <p>EDIT: oh, also won't work well if the array size gets too close to the time limit. If you want 1000 milliseconds and you have 2000 array elements, you'll end up passing in 0 for the period argument due to rounding. In that case you might as well run the for loop.</p> <p>EDIT 2: ah why not...</p> <pre><code>import java.util.Random; import java.util.Timer; public class LoopTest { private final static long desiredTime = 1000; public static void main(String[] args) { final float[] input = new float[512]; final Random rand = new Random(); for(int i = 0; i &lt; input.length; ++i) { input[i] = rand.nextFloat(); } final Timer timer = new Timer(); final LoopTask task = new LoopTask(input); double interval = ((double)desiredTime/((double)input.length)); long period = (long)Math.ceil(interval); final long t1 = System.currentTimeMillis(); timer.scheduleAtFixedRate(task, 0, period); while(!task.isDone()) { try { Thread.sleep(50); } catch(final InterruptedException i) { //Meh } } final long t2 = System.currentTimeMillis(); timer.cancel(); System.out.println("Ended up taking " + (t2 - t1) + " ms"); } } </code></pre> <hr> <pre><code>import java.util.TimerTask; public class LoopTask extends TimerTask { private final float[] input; private int index = 0; private boolean done = false; public LoopTask(final float[] input) { this.input = input; } @Override public void run() { if(index == input.length) { done = true; } else { //TODO: actual processing goes here System.out.println("Element " + index + ": " + input[index]); ++index; } } public boolean isDone() { return done; } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload