2013-01-06 22 views
2

我該如何製作一個循環,每秒執行約10000次(!)的間隔(!)?高頻迴路

(的continuous data acquisition from parallel port in Java重複的,但一個人的難以發現,而不是回答很老)

我看着Thread.sleep(long millis)Thread.sleep(long millis, int nanos)但在Windows甲骨文的J2SE虛擬機總是睡1 millesecond長於我指定。此外,納米字段似乎四捨五入到整個毫秒(驗證,這是在Thread.java的源代碼中進行硬編碼)。

Experimantal結果:

  • Thread.sleep(0)睡不(100%CPU)
  • Thread.sleep(1)睡在平均
  • Thread.sleep(0, 0)平均
  • Thread.sleep(2)睡2.95ms 1.95ms熟睡中不(100%CPU)
  • Thread.sleep(0, 1)睡眠平均1.95ms

那麼我怎樣才能讓一個循環以每秒500次以上的頻率循環呢?

編輯:我稍微放鬆了「常規」要求。如果一個延遲比另一個延遲短4倍(即,抖動不是問題),那麼這個問題不是一個大問題,只要最長的延遲是確定性的並且低於0.1ms。 (ScheduledExecutorService的情況並非如此)

+0

對於上下文,爲什麼你需要這樣做? –

+0

_loop每秒鐘執行大約10000次(#)interval_爲什麼你想要每秒鐘循環次數?! –

+5

如果您需要硬性保證,您需要考慮操作系統和代碼。告訴線程休眠1ms僅意味着(1)它進入休眠狀態,(2)它告訴其老闆(JVM或OS,取決於線程實現)在1ms過去之前不要喚醒它。但是,如果你的操作系統認爲有更重要的事情要做,你的線程*會*睡眠的時間比這個長。 – us2012

回答

2

我相信您在尋找ScheduledExecutorService(請參閱使用示例)。

具體地說

scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit)

Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on.

使用TimeUnit.MICROSECONDS。

+0

我試了一下,並得出結論,它只是在內部使用Thread.sleep(),並在每次延遲後趕上未接來電(所以它不是經常的) –

+1

@ Zom-B看到我對你的問題的評論。您至少需要在您的應用程序和OS內核之間的所有內容來尊重您的線程需求,至少在Java中包括JVM和OS調度程序。這完全不是一件容易的事情,因爲標準即用型操作系統的調度程序粒度大約爲10毫秒。你需要1ms的請求,每2ms發生一次請求,其他進程也要運行,並且你的操作系統和硬件必須非常節儉,並且有中斷和類似的事情。你的問題需要更多的工作,而不是找到一個適合你的Java庫。 – us2012

0

如果你確定100%的核心,你可以使用它在亞微秒間隔內獲得相當均勻分佈的事件。當然,如果使用這種方法達到最大吞吐量速率,那麼用較低成本的定時調用替換System.nanoTime()將是可取的。

long nanosBetweenMessages = getSpacing(); 
long lastSendTime = 0l; 
while (true) { 
    final long curTimeNanos = System.nanoTime(); 
    if (curTimeNanos - lastSendTime < nanosBetweenMessages) { 
     continue; 
    } 
    lastSendTime = curTimeNanos; 
    sendEvent(); 
    if (done()) { 
     break; 
    } 
} 

我只注意到你的10K /秒的要求......我目前使用這種計算與在的SendEvent()方法像樣的數目,在20K左右/秒的最大速度推進。

+0

良好的通話。我忘了把這個要求放在我的帖子裏。我所做的是一個後臺服務,不應以任何方式引人注目,所以100%cpu是不可能的。與此同時,我已經實現了一個緩衝輸入的JNA函數,以便Java可以按照自己的步調接收它們。 –