Я пытался собрать свой собственный таймер, отключив доступные функции и интуитивно представив, как таймер может работать вот так. Кажется, что он дает лучшие результаты, но все же есть странные колебания, некоторые из которых не имеют смысла с написанным кодом (изображение со статистикой). Мол, как задержка может быть меньше 5? Условием срабатывания функции является достижение отложенной временной метки. Может ли это быть какое-то странное состояние гонки?
регистрируемые задержки времени, выводимые функцией runFunc(), выполняемой в потоке
Это весь тестовый класс для этого (просто удалена строка пакета).
Код: Выделить всё
public class TimerTest {
// for debug
public double averageTimeMillis;
int timesLogged;
// Timer vars
long lastTickTimeMillis;
long lastTickTimeNano;
long nextTimestampNano;
long delayNano;
public TimerTest(long delayNano) {
timesLogged = 0;
averageTimeMillis = delayNano;
lastTickTimeMillis = System.currentTimeMillis();
lastTickTimeNano = System.nanoTime();
this.delayNano = delayNano;
nextTimestampNano = lastTickTimeNano+delayNano;
new Thread(this::run).start();
}
private void run() {
for (;;) {update();}
}
private void update() {
long timeNowNano = System.nanoTime();
if (timeNowNano>nextTimestampNano) {
// Run, or threaded*
new Thread(this::runFunc).start();
// runFunc();
nextTimestampNano+=delayNano;
}
}
private void runFunc() {
long timeNowMillis = System.currentTimeMillis();
long timeNowNano = System.nanoTime();
long millisDelay = timeNowMillis - lastTickTimeMillis;
long nanoDelay = timeNowNano - lastTickTimeNano;
averageTimeMillis = (averageTimeMillis*timesLogged+millisDelay)/(timesLogged+1);
timesLogged++;
System.out.println(millisDelay + " | " + nanoDelay + " | " + averageTimeMillis);
lastTickTimeMillis = timeNowMillis;
lastTickTimeNano = timeNowNano;
}
public static void main(String[] args) {
new TimerTest(5000000); // 5 ms delay, just for testing, in game will be higher
for (;;) {} // to let timer run
}
}
У кого-нибудь, кто имел опыт работы с этим в Java, есть какие-нибудь советы о том, почему могут возникать колебания и как это исправить?
Я пробовал отладку, однако специфика задачи усложняет эту задачу, и я не добился хороших результатов.
Я попробовал увеличить задержку, что на самом деле так и будет следует использовать с задержкой не менее 10-20 мс, и это, кажется, минимизирует колебания, но только потому, что они, похоже, не масштабируются с задержкой, поэтому они оказывают меньшее влияние на большие числа. Кажется, что их частота не изменилась (на первый взгляд).
Подробнее здесь: https://stackoverflow.com/questions/791 ... to-improve