2011-10-31 108 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

相關問題