如何在 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 循环行所花费的时间。
完成所有这些之后,我将 now
和 lastTime
的差异除以 1/60 秒(ns
)我提到.这意味着每次 delta
等于 1 时,将过去 1/60 秒。
紧接着,我将 lastTime
设为与 now
相同。在随后出现的 while 循环中,我检查 delta 是否等于或大于 1,然后在其中放置所有你希望每秒执行 60 次的代码。不要忘记从 delta
中减去 1,这样它就不会无限循环。
把代码分析透彻,看看能不能看懂。如果你不能,我会进一步澄清。我坚持认为这只是一种可能的方法,但还有更多方法。
注意:在某些情况下,您甚至不需要 delta
,但它对某些用途非常有用。
代码的来源:此代码的大部分(至少在我获得和学习的地方)是从 TheCherno's Game Programming Series
中提取的
祝你有美好的一天!
如果我不控制代码每秒执行的次数,当我添加一行时,程序会发生变化,我必须再次调整常量。 (由 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 循环行所花费的时间。
完成所有这些之后,我将 now
和 lastTime
的差异除以 1/60 秒(ns
)我提到.这意味着每次 delta
等于 1 时,将过去 1/60 秒。
紧接着,我将 lastTime
设为与 now
相同。在随后出现的 while 循环中,我检查 delta 是否等于或大于 1,然后在其中放置所有你希望每秒执行 60 次的代码。不要忘记从 delta
中减去 1,这样它就不会无限循环。
把代码分析透彻,看看能不能看懂。如果你不能,我会进一步澄清。我坚持认为这只是一种可能的方法,但还有更多方法。
注意:在某些情况下,您甚至不需要 delta
,但它对某些用途非常有用。
代码的来源:此代码的大部分(至少在我获得和学习的地方)是从 TheCherno's Game Programming Series
中提取的祝你有美好的一天!