2011-05-23 45 views
9

下面的代碼:了Thread.sleep等待超過預期

long msBefore = System.currentTimeMillis(); 
//Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 
try 
{Thread.sleep(200); 
} catch (InterruptedException e){} 
System.out.println("Time: " + (System.currentTimeMillis() - msBefore)); 

打印:

Time: 578 
Time: 594 
Time: 625 
Time: 640 
Time: 641 
Time: 609 
Time: 625 
Time: 625 
Time: 610 
Time: 609 
Time: 625 
Time: 625 
Time: 422 
Time: 625 
Time: 594 
Time: 609 
Time: 625 
Time: 594 
Time: 594 
Time: 625 

哪裏的問題?

+0

儘管您的系統要求精確,但它應該比這更接近。在我的Windows和Linux系統上,它很少超過預期的2毫秒。你有什麼操作系統? – 2011-05-23 12:02:01

+0

嗨,穆罕默德。正如其他人指出的那樣,這將取決於您的系統的準確性(即使是環境因素,例如溫度可能會發生變化)。出於好奇,你試圖通過這個代碼來解決的實際問題是什麼?根據你的答案,這裏的某個人可能會以更好的方式幫助你做到這一點(例如,TimerTaskExecutor對於打印定期檢測信號會更準確)。請確保您以不同的線索提出問題。乾杯。 – 2011-05-23 12:21:09

+0

我以後運行過幾次,現在它的準確度很高。謝謝大家的幫助。 – 2011-05-24 08:15:29

回答

7

這裏是沒有問題的。來自javadoc:

受制於系統和 調度程序的準確性。

通常,依賴休眠間隔是一個糟糕的設計,因爲它可能在不同的系統和JVM實現上有所不同。改用wait()和notify(),或者更好 - 使用java.util.concurrent包。

+0

我有一個要求每秒發送n條消息,我認爲等待/通知不適合,正確嗎? – 2011-05-23 10:13:58

+1

使用Timer類來做到這一點。 – 2011-05-23 10:16:34

+3

等待/通知使用與睡眠相同的定時器。它同樣精確。 – 2011-05-23 11:59:49

8

我有一個要求每秒發送n條消息,我認爲等待/通知不適合,正確嗎?

如果你有一個困難的時間要求,那麼你將需要使用real-time Java實現。主流SE和ME Java實現不適用於硬實時應用程序。

有你可以用它來滿足這些要求「大部分時間」各種招數......但如果你的應用/系統超載你容易開始缺少必要的信息傳輸率。

釷真正的問題不是定時器的準確性,但事實證明,非實時調度程序不會(也不能)保證調度線程一旦定時器超時運行。

+0

感謝您的鏈接和信息。 – 2011-05-24 08:16:01

0

你沒有考慮到它花費的處理時間。

try { 
     long processingStart = System.currentTimeMillis(); 

     long processingFinish = System.currentTimeMillis(); 
     long processTime = 600 - (processingFinish - processingStart); 
     Thread.sleep(processTime); 

    } catch (InterruptedException ex) { 

    } 
0

如果您確實需要固定消息速率,請執行類似自旋鎖的操作。它會消耗單個CPU內核,但讓你關閉。

long nextTime = System.currentTimeMillis() + interval; 
while (keepRunning) { 
    while (nextTime - System.currentTimeMillis() > 0) 
     ; 
    sendMessage(); 
    nextTime += interval; 
}