Точность System.nanoTime () для измерения прошедшего времени уменьшается после вызова Thread.sleep ()

Я столкнулся с действительно необычной проблемой здесь. Похоже, что вызов Thread.sleep (n), где n> 0, сделает следующие вызовы System.nanoTime () менее предсказуемыми.

Код ниже демонстрирует проблему.

Запуск его на моем компьютере (rMBP 15 "2015, OS X 10.11, jre 1.8.0_40-b26) дает следующий результат:

Control: 48497
Random: 36719
Thread.sleep(0): 48044
Thread.sleep(1): 832271

На виртуальной машине под управлением Windows 8 (VMware Horizon, Windows 8.1, 1.8.0_60-b27):

Control: 98974
Random: 61019
Thread.sleep(0): 115623
Thread.sleep(1): 282451

Однако, запустив его на корпоративном сервере (VMware, RHEL 6.7, jre 1.6.0_45-b06):

Control: 1385670
Random: 1202695
Thread.sleep(0): 1393994
Thread.sleep(1): 1413220

Что удивительно, результат, который я ожидаю.

Очевидно, что Thread.sleep (1) влияет на вычисление приведенного ниже кода. Я понятия не имею, почему это происходит. У кого-нибудь есть ключ?

Спасибо!

public class Main {
    public static void main(String[] args) {
        int N = 1000;
        long timeElapsed = 0;
        long startTime, endTime = 0;

        for (int i = 0; i < N; i++) {
            startTime = System.nanoTime();
            //search runs here
            endTime = System.nanoTime();

            timeElapsed += endTime - startTime;
        }

        System.out.println("Control: " + timeElapsed);

        timeElapsed = 0;

        for (int i = 0; i < N; i++) {
            startTime = System.nanoTime();
            //search runs here
            endTime = System.nanoTime();

            timeElapsed += endTime - startTime;

            for (int j = 0; j < N; j++) {
                int k = (int) Math.pow(i, j);
            }
        }

        System.out.println("Random: " + timeElapsed);

        timeElapsed = 0;

        for (int i = 0; i < N; i++) {
            startTime = System.nanoTime();
            //search runs here
            endTime = System.nanoTime();

            timeElapsed += endTime - startTime;

            try {
                Thread.sleep(0);
            } catch (InterruptedException e) {
                break;
            }
        }

        System.out.println("Thread.sleep(0): " + timeElapsed);

        timeElapsed = 0;

        for (int i = 0; i < N; i++) {
            startTime = System.nanoTime();
            //search runs here
            endTime = System.nanoTime();

            timeElapsed += endTime - startTime;

            try {
                Thread.sleep(2);
            } catch (InterruptedException e) {
                break;
            }
        }

        System.out.println("Thread.sleep(1): " + timeElapsed);
    }
}

По сути, я выполняю поиск в цикле while, который прерывает каждую итерацию, вызывая Thread.sleep (). Я хочу исключить время ожидания из общего времени, затраченного на поиск, поэтому я использую System.nanoTime () для записи времени начала и окончания. Однако, как вы заметили выше, это не работает хорошо.

Есть ли способ исправить это?

Спасибо за любой вклад!

Ответы на вопрос(3)

Ваш ответ на вопрос