繁体   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