Почему занятое ожидание менее 15 мс несовместимо?
Я делаю проект симуляции, где у меня есть сотни связанных с CPU заданий, работающих в течение 10-50 миллисекунд. Задание - это объект Runnable с указанным временем выполнения, для которого задание будет загружать ЦП. В пуле потоков есть 10 потоков, ожидающих прибытия на работу. Я установил частоту запросов на 40 запросов в секунду, а время выполнения всех заданий установлено на 10 мс. Но результаты так ужасны. Все задания выполняются не менее 15 мс. Нет работы, которая работает в течение 10 мс. Я проверил эксперимент с заданиями на 15 мс, и я получил правильный результат. Почему задания 10 мс выполняются как минимум 15 мс?(Я использую WINDOWS8).
public class CpuBoundJob implements Runnable {
long runningTime
public CpuBoundJob(long runningTime) {
this.runningTime=runningTime;
}
@Override
public void run() {
long timeToWait = this.runningTime;
long startTime = System.currentTimeMillis();
while(startTime + timeToWait > System.currentTimeMillis());
}
}
1 ответ
Во многих системах (особенно Windows, IIRC), System.currentTimeMillis()
поддерживается часами с точностью до 15 миллисекунд или около того.
Однако это еще хуже: System.currentTimeMillis()
измеряет время с эпохи Unix, измеренное вашими системными часами. Поэтому, если вы измените время на своем компьютере (например, из-за синхронизации системных часов с источником времени, или из-за високосной секунды, или из-за ряда других вещей), тогда currentTimeMillis()
может прыгать вперед или назад произвольно большое количество времени.
Если вы хотите измерить прошедшее время, НИКОГДА не используйте currentTimeMillis()
, использование System.nanoTime()
вместо. В качестве бонуса, на большинстве систем это также значительно дешевле для вызова и значительно более точным.