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

huangapple go评论133阅读模式
英文:

how to run a code 60 times per second in java

问题

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

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

if I don't control the number of times per second my code executes, when I add a line, the program varies and I have to adjust the constants again. (translated by Google)
My code running out of control:

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

答案1

得分: 2

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

public class HelloWorld {
    public static void main(String []args) {
        // 表示 1/60 秒中的毫秒数
        // 这里可能会有一些四舍五入误差,
        // 不确定这是否适用于您的用例
        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!"); 
    }
}
英文:
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!"); 
    }
}

答案2

得分: 2

这只是一种方法(非常冗长但非常精确 - 我推荐用于游戏开发)。在这种情况下,我使用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){
            // 要执行的代码
            delta--;
        }
    } 
}

逐行解释:

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

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

在做完所有这些之后,我将delta增加了nowlastTime之差除以我提到的1/60秒(ns)。这意味着每当delta等于1时,将经过1/60秒。

紧接着,我让lastTimenow相同。在随后的while循环中,我检查delta是否等于或大于1,然后在其中,您应该放置您想要每秒执行60次的所有代码。不要忘记从delta中减去1,这样它就不会无限循环。

仔细分析代码,看看是否能够理解。如果不能,我会进一步进行说明。我坚持认为这只是一种可能的方法,但还有许多其他方法。

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

代码来源:大部分(至少我获取和学习的部分)来自TheCherno的游戏编程系列

祝您度过愉快的一天!

英文:

This is just one way to do it(it's very long but VERY precise - I recommend it for game development). In this case I'm using the run() method from the Runnable interface to execute the code.

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

Explanation Line by Line:

Basically, I store the current time in nanoseconds in lastTime. Then in ns I store 1/60th of a second in nanoseconds and create a variable delta.

After this, I go inside the infinite while loop(it doesn't have to be infinite) and store the current time in nanoseconds once again in now. This is to take into account the amount of time that took the computer to go from the lastTime declaration line to the while loop line.

After doing all this, I add to delta the difference of now and lastTime divided by the 1/60th of a second(ns) I mentioned. This means that every time delta is equal to 1, 1/60th of a second will have passed.

Right after this, I make lastTime be the same as now. In the while loop that comes afterwards I check if delta is equal or greater than 1 and then in there you should put all the code you want to be executed 60 times per second. Don't forget to substract 1 from delta so it doesn't loop endlessly.

Analyze the code thoroughly and see if you can understand it. If you can't, I'll clarify further. I insist that this is just one possible way to do it, but there are many more ways.

Note: In some cases, you will never even need delta, but it is very helpful for some purposes.

Credit for the code: Most of this code(at least where I got it & learned it) is extracted from TheCherno's Game Programming Series

Have a great day!

答案3

得分: -1

基本上,您需要每17毫秒执行一次stepEvent

在假设您想要顺序运行的情况下,您可以通过使用Thread.sleep(millis, nanos)在一段定义的时间内停止执行。在这种情况下,我们将在线程执行时间为17毫秒减去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来使用多个线程。

英文:

Basically, you have to execute your stepEvent every 17 ms.

With the assumption you want to run sequentially, you could stop the execution during a defined period by using Thread.sleep(millis , nanos). In this case, we will stop the thread 17ms minus the stepEvent execution time (think to add condition to avoid negative value in sleep function)

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

Otherwise you can use the ScheduledExecutorService which allows you to schedule code to run periodically at fixed time intervals (or after a specified delay). In this case, you can execute your step at a fixed rate every 17ms.

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

You can also configure to use severals thread with Executors.newScheduledThreadPool

huangapple
  • 本文由 发表于 2020年8月21日 09:16:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63515194.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定