Колебания задержки таймера в Java – как улучшить?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Колебания задержки таймера в Java – как улучшить?

Сообщение Anonymous »

Я пытаюсь создать класс таймера для игры. До сих пор я просто использовал javax.swing.Timer, но после попытки выполнить некоторые операции, требующие более точного времени (в частности, визуальную интерполяцию между состояниями двух тиков при рендеринге большего количества кадров, чем есть тактов), я обнаружил ограничения этого класса и он оказался непригодным для использования.
Я пытался собрать свой собственный таймер, отключив доступные функции и интуитивно представив, как таймер может работать вот так. Кажется, что он дает лучшие результаты, но все же есть странные колебания, некоторые из которых не имеют смысла с написанным кодом (изображение со статистикой). Мол, как задержка может быть меньше 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
}
}
Еще одно странное наблюдение: после комментария «//Run или threaded*» запуск функции обычно дает значительно меньшие колебания, чем запуск ее в потоке. Причина, по которой я это сделал, заключается в том, что я не хочу, чтобы запуск функции замедлял таймер, если бы он работал дольше, чем задержка. Но теперь, когда я думаю о том, как будут работать два экземпляра runFunc(), одновременно изменяющие одно и то же состояние, отсутствие потоков может быть правильным подходом. Однако он по-прежнему часто вызывает колебания. колебания с помощью runFunc() не в новом потоке
У кого-нибудь, кто имел опыт работы с этим в Java, есть какие-нибудь советы о том, почему могут возникать колебания и как это исправить?
Я пробовал отладку, однако специфика задачи усложняет эту задачу, и я не добился хороших результатов.
Я попробовал увеличить задержку, что на самом деле так и будет следует использовать с задержкой не менее 10-20 мс, и это, кажется, минимизирует колебания, но только потому, что они, похоже, не масштабируются с задержкой, поэтому они оказывают меньшее влияние на большие числа. Кажется, что их частота не изменилась (на первый взгляд).

Подробнее здесь: https://stackoverflow.com/questions/791 ... to-improve
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»