В приложении, чувствительном к времени в java, я пытаюсь построить данные каждые 100 мс. Я пробовал называть код построения трех способов:
1) Внутри метода внутри кода 2) Внутри таймера, установленного на 100 мс 3) Внутри другой нити
При всех трех методах синхронизация нестабильна (варьируется от 90 до 110 мс), но как только я открываю Firefox или Chrome и открываю новую вкладку, время становится квазисовершенным (99 - 100 мс).
Почему веб-браузеры влияют на/улучшают сроки? Могу ли я изменить свой код, чтобы исправить эту проблему и обеспечить синхронизацию 100 мс (+ / -1ms)?
Я бы предположил, что браузер больше использует процессор, не позволяя ему перейти в режим ожидания, который может быть менее стабильным с точки зрения времени. Вы можете рассмотреть возможность выполнения какой-либо работы, которую ваше приложение может захотеть сделать (или даже бесполезной работы, такой как поиск простых чисел) в потоке с низким приоритетом, чтобы процессор не попал в состояние ожидания.
Я протестировал его, и это определенно не связано с процессором, работая с программным обеспечением, голодное программное обеспечение не имело никакого значения. Он напрямую связан с веб-браузером, который, скорее всего, работает в фоновом режиме Java-апплетами и влияет на VM.
Я смог решить проблему, создав 2 разных потока и синхронизируя их, 1 поток для связи и еще один для построения графика, таким образом приложение не требовало такой точности во времени, чтобы я мог избежать игры со временем.
Наконец, то, что он сделал, имеет огромное значение, так это то, как я рассчитывал время. Я использовал System.currentTimeMillis(), чтобы прочитать время, я начинаю использовать System.nanoTime(), и эта функция более точна и не затрагивается веб-браузером. Мораль: когда вам нужно точно измерять время, старайтесь всегда использовать System.nanoTime().
Вы не можете гарантировать, что какой-либо конкретный временной интервал будет составлять 100 миллисекунд + - 1 миллисекунда. Тем не менее, вы можете усреднить временные несоответствия, как указано в его комментариях CodeChimp.
Вам нужно создать цикл сна, и вы отрегулируете время сна в зависимости от того, сколько времени потребуется для получения и построения ваших данных. Если вы используете Swing для построения данных, у вас мало контроля, когда происходит заговор.
В некоторых операционных системах System.currentTimeMillis не является точным до 1 миллисекунды.
Вот какой код времени, чтобы проиллюстрировать, о чем говорит CodeChimp.
public void timingLoop() {
long constantSleepTime = 100L;
boolean running = true;
while(running) {
long startTime = System.currentTimeMillis();
getData();
plotData();
long elapsedTime = System.currentTimeMillis() - startTime;
long sleepTime = constantSleepTime - elapsedTime;
// We have to sleep for a short time, even if sleep
// time is negative.
sleepTime = Math.max(sleepTime, 5L);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
}
startTime = System.currentTimeMillis();
}
}
Потоки работают с процессорными временными срезами, когда вы запускаете свой браузер (или любую другую "тяжелую" программу), вы потребляете больше CPU, что должно сделать систему более "предупреждающей" о том, как распределяются эти временные фрагменты.
К сожалению, такой подход относится к поведению на уровне машины, поэтому кодекс (на другом уровне виртуализации, то есть JVM) вряд ли может быть более точным.