簡體   English   中英

Java如何在1ms下精准休眠

[英]How Java precise sleep under 1ms

我正在研究 swing 和 graphic2D,我遇到了一些問題,如何精確睡眠?

因為對於 144 或 240 fps 的顯示器來說,ms 太長了。 使用 4.1667ms Thread.sleep 將導致非常不穩定的結果並且時間被縮放。 問題是有什么方法可以在 1 毫秒內實現真正的睡眠嗎?

我做了一些研究,發現類似Thread.Sleep 的時間不到 1 毫秒

根據帖子,Event sleep(1) will not sleep accurate 1ms, 正如我的測試有 100 次結果:

551900
1932500
994600
939200
1903000
935000
958700
944200
938700
950800
953600
1920600
932500
954000
961700
1927400
930900
1936800
1913000
926500
1976200
957800
952000
940600
961000
971700
994800
1889500
1989800
907600
966100
1983600
1914300
1943300
999900
1911200
1988600
932500
1836100
1955500
913500
970200
956400
1902200
970300
1985300
1926100
990900
1804000
947700
1881400
933500
1963600
963000
928300
1913600
1016900
1824700
951600
1959900
938400
1951400
1957300
1965600
969400
1933800
936700
980000
961900
929500
1910000
936700
940100
976100
1975600
952100
986000
1959900
919300
1973500
1998700
1852000
931400
967500
1954200
2005800
1897200
968700
1925500
1945700
1917600
1946300
933200
957100
966400
944900
916000
934300
1887200
934200

它們都不是很接近,至少會導致 10ms,有些甚至超過 20ms!

即使是 60FPS 顯示器,20ms 也是不可接受的。 因為16.67ms是幀率。

我尋求進入 Thread.sleep

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);
}

我什至不敢相信 java 只是將納秒視為毫秒,如果超過 0.5 毫秒,而其他諸如 TimeUnit.sleep 或 Object.wait 的東西只是調用 thread.sleep 或轉換為毫秒內部。 那么這是否意味着在 windows 或 linux 或任何非實時操作系統中,沒有辦法精確睡眠? 游戲引擎如何做到這一點?

你不需要自己睡覺。 你應該盡可能快地運行你的代碼。 監視器將幫助您同步視頻輸出,您不必讓代碼等待監視器。

游戲引擎依賴 Delta 時間來使游戲幀率獨立,Delata 時間只不過是最后一幀和當前幀之間經過的時間。 您可以將增量時間測量為

DeltaTime = 1/FPS

因此,您可以使用此變量通過將其與您的游戲變量相乘來使游戲獨立,例如,如果您想獨立於幀速率移動玩家,您可以執行類似的操作

Player.position = Player.position + MovementSpeed * DeltaTime

如果初始position = 10 , MovementSpeed = 1如果FPS = 60 , DeltaTime = 0.016666667那么 1 秒后的距離是

Player.position = 10 + 1 * (0.016666667*60)即“11”(這里乘以 60 只是為了適應這樣一個事實:當游戲以 60 FPS 運行時,相同的計算將運行 60 次,因此 Player.position 將是由 0.016666666 更新 60 次)

如果FPS = 30DeltaTime = 0.03333則 1 秒后移動的距離為Player.position = 10 + 1*(0.03333*30)即 '11' 所以游戲可以獨立於幀速率運行

您可以嘗試計算 DeltaTime,如:

//In main Game loop
current time = getSystemTime()
Delta time = current time - old time 
old time = current time // save old time for next loop

Thread.sleep有兩種方法,其中一種接受納秒。

 Thread.sleep(long millis, int nanos)

所以Thread.sleep(1); 等於Thread.sleep(0,1000000);

所以如果你想睡半毫秒,使用

Thread.sleep(0,500000)

有用的網址:-

向 Java 代碼添加十進制毫秒延遲

線程可以在 Java/其他語言中睡眠少於半毫秒嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM