在特定时间范围内读取数组
如何在特定时间内读取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++){
}
你需要一个Timer。看看它的方法......它们有很多,但它们可以分为两类:按固定延迟进行安排的方法(schedule(...
方法)和按固定比例安排的方法(方法scheduleAtFixedRate(...
)。
如果您需要“平滑度”,固定延迟是您想要的。这意味着,执行任务之间的时间大多是不变的。这就是你在游戏中需要动画的东西,只要平均延迟在你的目标时间附近,一次执行可能会滞后一点就没关系。
如果您需要任务的执行时间达到总时间,则固定费率就是您想要的。换句话说,所有执行的平均时间必须保持不变。如果一些执行被延迟,那么可以运行多个执行“追赶”。这与固定延迟不同,因为某个任务可能会“错过”其提示,因此任务不会更快运行。
我估计固定利率是你之后。所以你需要先创建一个新的Timer
。那么你需要调用方法scheduleAtFixedRate(TimerTask task, long delay, long period)
。如果希望定时器立即启动,那么第二个参数可以是0。第三个参数应该是任务运行之间的时间。在你的情况下,如果你想要总时间为1000毫秒,它将是1000 /数组大小。不像你所做的那样,不是数组大小/ 1000。
让我们留下第一个参数:a TimerTask。请注意,这是一个抽象类,只需要执行run()
方法。所以你需要创建一个子类并实现该方法。由于您正在操作数组,因此您需要通过构造函数将该数组提供给您的实现。然后你可以保存一个索引,最后处理哪个元素,每增加一个元素run()
。基本上,你用计数器替换for循环的run()
方法。显然,如果柜台已经达到最后一个元素,你就不应该做任何事情。在这种情况下,你可以在你的TimerTask实现中设置一些(布尔)标志来指示最后一个元素被处理。
在创建TimerTask并在Timer上调度它之后,需要等待TimerTask的标志置位,表示它已完成其工作。然后你可以拨打定时器上的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;
}
}
他也可以使用ScheduledExecutorService,它是java.util.Timer的替代品。 –
@JBNizet See,我总是怀疑'java.util.concurrent'中有更好的东西,但是随后我看了一下包,我的视线开始变得模糊。我真的很需要学习这个API。 –
非常感谢。我会尽我所能来实现这一点。 – menemenemu
更改步骤为每数时间(或总时间是通过以下步骤数除以)
float step = 1000.0/e.length;
内部的for()循环:
try{
Thread.sleep(step);
}catch(InterruptedException e){
e.printStackTrace();
}
谢谢Tim,但是和上面一样。线程睡眠不准确。 – menemenemu
你读它比快。实际上你的要求是什么? – Bozho
让我直截了当地说:你想要以这样的时间间隔来处理数组中的每个元素,那么处理整个数组将花费一定的时间?像1秒? –
是的,我想在1秒内读取孔阵列 – menemenemu