2016-03-08 60 views
9

[編輯]:得到的回答後,我明白它不是特定於Java,它涉及到OS調度器一樣,所以添加其他標籤線程可以在Java /其他語言中睡眠少於半毫秒嗎?

是否有可能在Java中,使一個線程睡眠納米秒。

當然,在查看線程api,我們可以在睡眠方法中通過納秒,答案可能是肯定的。

但看在Thread class執行/睡眠方法的來源,這是後我懷疑:

public static void sleep(long millis, int nanos) 
throws InterruptedException { 
    if (millis < 0) { 
     throw new IllegalArgumentException("timeout value is negative"); 
    } 

    if (nanos < 0 || nanos > 999999) { 
     throw new IllegalArgumentException(
          "nanosecond timeout value out of range"); 
    } 

    if (nanos >= 500000 || (nanos != 0 && millis == 0)) { 
     millis++; 
    } 

    sleep(millis); 
} 

現在根據邏輯它是由1增加毫秒如果傳遞的納米秒超過半毫秒。但是這聽起來對我來說不合邏輯,可以說我已經寫了一個代碼,其中一個線程正在等待說一些40000 nano seconds(在實際情況下可能不是這種情況),這小於半毫秒,這意味着我的線程不會等待在所有。

有人可以請評論相同和爲什麼這個設計決定等待毫秒而不是納秒秒

還有什麼可以保證線程準確地醒來?

+0

什麼能保證線程正確地喚醒? – biziclop

+0

@biziclop完全。我將編輯我的問題來添加這一點 – Vishrant

+0

@dr_debug它不重複,我問爲什麼選擇這個設計,而不是讓線程睡幾秒鐘 – Vishrant

回答

9

您可以使用LockSupport's parkNanos

LockSupport.parkNanos(400_000); 

然而,這是不一樣的睡眠(這是不可中斷的)和所有它的作用是將請求傳遞給操作系統。例如,在Windows 8上,即使parkNanos(1)可能會睡1毫秒。

由於biziclop指出,還有的Javadoc提到

該調用不合邏輯地(即毫無理由地)返回。

這種情況在我的經驗中很少發生,但確實發生了。


但是,你說得對,Thread.sleep()總是會休眠至少1 ms。在Win XP上,它可能會睡眠16毫秒(1/60秒)

另外,如何確保線程能夠準確喚醒?

使用實時操作系統。

我所做的就是不要去睡覺,而是要忙於等待。這樣我就可以更準確地停下一段時間。如果一個孤立的CPU(在Linux中)上運行的線程可以減少變化約10微秒

繁忙的例子等待

long end = System.nanoTime() + delay; 
while (System.nanoTime() < end) { /* busy waiting */ } 

,或者如果你想稍微友好

while (System.nanoTime() < end) 
    Thread.yield(); 
+0

@jtahlborn我不確定你的意思。它是一個名爲'LockSupport'的類,內置了一個'parkNanos'方法,我添加了一個Javadoc。 –

+2

我特別喜歡他們承認'parkNanos()'可能會在沒有明顯理由的情況下返回的事實。 – biziclop

+0

@Peter Lawrey在Win XP上,它可能會睡眠16毫秒(1/60秒)'爲什麼會這樣,是基於操作系統的工作原理?無論如何,我們可以將它縮小到16ms以下嗎?我在幾個月前發佈了一個類似的問題,沒有人能夠回答它。 – user3437460