在特定时间范围内读取数组

时间:2011-10-31 22:24:22

标签: java time interpolation

如何在特定时间内读取java中的数组?让我们说1000毫秒。

例如:

float e[]=new float [512];
float step = 1000.0 / e.length; // I guess we need something like that?
for(int i=0; i<e.length; i++){

}

2 个答案:

答案 0 :(得分:3)

你需要Timer。看看它的方法......有很多方法,但它们可以分为两类:按固定延迟计划的那些(schedule(...方法)和以固定速率计划的方法( scheduleAtFixedRate(...方法)。

如果您需要“平滑度”,则需要固定延迟。这意味着,任务执行之间的时间大多是不变的。这将是你在游戏中动画所需要的东西,只要平均延迟在你的目标时间附近,只要一次执行可能会落后一点就可以了。

如果您要求任务的执行达到总时间,则需要固定费率。换句话说,所有执行的平均时间必须是不变的。如果某些执行被延迟,那么之后可以运行多个执行以“赶上”。这与固定延迟不同,在固定延迟中,任务不会更快地运行,因为有人可能“错过”了它的提示。

我认为固定利率是你所追求的。因此,您需要先创建一个新的Timer。然后你需要调用方法scheduleAtFixedRate(TimerTask task, long delay, long period)。如果您希望计时器立即启动,则第二个参数可以为0。第三个参数应该是任务运行之间的时间。在您的情况下,如果您希望总时间为1000毫秒,则它为1000 /数组大小。不像你那样使用数组大小​​/ 1000。

这给我们留下了第一个论点:TimerTask。请注意,这是一个抽象类,只需要实现run()方法。所以你需要创建一个子类并实现该方法。由于您在阵列上操作,因此您需要通过构造函数将该数组提供给您的实现。然后,您可以保留上次处理哪个元素的索引,并在每次调用run()时递增。基本上,您使用计数器用run()方法替换for循环。显然,如果计数器已到达最后一个元素,您将不再执行任何操作。在这种情况下,您可以在TimerTask实现中设置一些(布尔)标志,指示最后一个元素已被处理。

创建TimerTask并在Timer上调度后,您需要等待TimerTask的标志置位,表明它已完成其工作。然后你可以在Timer上调用cancel()来阻止它。否则,它会继续在任务上调用无用的run()方法。

请记住以下几点:如果在run()方法中完成的工作通常需要的时间超过两次执行之间的时间间隔(在您的情况下大约为2毫秒),这将无法正常工作。如果for循环通常需要不到1秒的时间来完成,那么这样做才有意义。最好少得多。

编辑:哦,如果数组大小太接近时间限制也不会很好。如果你想要1000毫秒并且你有2000个数组元素,那么由于四舍五入,你最终会传入0作为句点参数。在这种情况下,你也可以运行for循环。

编辑2:啊为什么不......

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 < 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");

    }

}

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

}

答案 1 :(得分:0)

将您的步骤更改为每个号码的时间(或总时间除以步数)

float step = 1000.0 / e.length;

在for()循环中:

try{
   Thread.sleep(step);
}catch(InterruptedException e){
   e.printStackTrace();
}