如何在 java 中每秒 运行 代码 60 次

how to run a code 60 times per second in java

如果我不控制代码每秒执行的次数,当我添加一行时,程序会发生变化,我必须再次调整常量。 (由 Google 翻译) 我的代码运行失控:

public builder(){
    while(true)
        stepEvent();
}
private void stepEvent() {
    setOfActions();
    repaint();
}

基本上,您必须每 17 毫秒执行一次 stepEvent

假设您想要按顺序 运行,您可以使用 Thread.sleep(millis , nanos) 在定义的时间段内停止执行。在这种情况下,我们将停止线程 17ms 减去 stepEvent 执行时间(考虑添加条件以避免睡眠函数中的负值)

long startedTime;
for(;;){
    startedTime = System.currentTimeMillis(); 
    stepEvent();
    Thread.sleep(17 - System.currentTimeMillis() + startedTime);
}

否则,您可以使用 ScheduledExecutorService,它允许您以固定的时间间隔(或在指定的延迟后)定期将代码安排到 运行。在这种情况下,您可以每 17 毫秒以固定速率执行您的步骤。

ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
scheduledExecutorService.scheduleAtFixedRate(YourClass::stepEvent, 0, 17, TimeUnit.MILLISECONDS);

您还可以配置使用多个线程 Executors.newScheduledThreadPool

import java.util.Timer;
import java.util.TimerTask;

public class HelloWorld {
    public static void main(String []args) {
        // number of ms in 1/60 of a second
        // there will be some rounding error here,
        // not sure if that's acceptable for your use case
        int ms = 1000 / 60;
        Timer timer = new Timer();
        timer.schedule(new SayHello(), 0, ms);
     }
}

class SayHello extends TimerTask {
    public void run() {
       System.out.println("Hello World!"); 
    }
}

这只是一种方法(它很长但非常精确 - 我推荐它用于游戏开发)。在这种情况下,我使用 Runnable 接口中的 run() 方法来执行代码。

public void run(){
    long lastTime = System.nanoTime();
    final double ns = 1000000000.0 / 60.0;
    double delta = 0;
    while(true){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        while(delta >= 1){
            the code you want to be executed 
            delta--;
            }
        } 
   }

逐行解释:

基本上,我将当前时间以纳秒为单位存储在 lastTime 中。然后在 ns 中我以纳秒为单位存储 1/60 秒并创建一个变量 delta.

在此之后,我进入无限 while 循环(它不必是无限的)并再次将当前时间以纳秒为单位存储在 now 中。这是为了考虑计算机从 lastTime 声明行到 while 循环行所花费的时间。

完成所有这些之后,我将 nowlastTime 的差异除以 1/60 秒(ns)我提到.这意味着每次 delta 等于 1 时,将过去 1/60 秒。

紧接着,我将 lastTime 设为与 now 相同。在随后出现的 while 循环中,我检查 delta 是否等于或大于 1,然后在其中放置所有你希望每秒执行 60 次的代码。不要忘记从 delta 中减去 1,这样它就不会无限循环。

把代码分析透彻,看看能不能看懂。如果你不能,我会进一步澄清。我坚持认为这只是一种可能的方法,但还有更多方法。

注意:在某些情况下,您甚至不需要 delta,但它对某些用途非常有用。

代码的来源:此代码的大部分(至少在我获得和学习的地方)是从 TheCherno's Game Programming Series

中提取的

祝你有美好的一天!