2011-10-31 116 views
0

如何在特定时间内读取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

你读它比快。实际上你的要求是什么? – Bozho

+1

让我直截了当地说:你想要以这样的时间间隔来处理数组中的每个元素,那么处理整个数组将花费一定的时间?像1秒? –

+0

是的,我想在1秒内读取孔阵列 – menemenemu

回答

3

你需要一个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; 
    } 

} 
+1

他也可以使用ScheduledExecutorService,它是java.util.Timer的替代品。 –

+0

@JBNizet See,我总是怀疑'java.util.concurrent'中有更好的东西,但是随后我看了一下包,我的视线开始变得模糊。我真的很需要学习这个API。 –

+0

非常感谢。我会尽我所能来实现这一点。 – menemenemu

0

更改步骤为每数时间(或总时间是通过以下步骤数除以)

float step = 1000.0/e.length; 

内部的for()循环:

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

谢谢Tim,但是和上面一样。线程睡眠不准确。 – menemenemu

相关问题