La precisión de System.nanoTime () para medir el tiempo transcurrido disminuye después de una llamada a Thread.sleep ()

Me encuentro con un problema realmente inusual aquí. Parece que la llamada de Thread.sleep (n), donde n> 0 causaría que las siguientes llamadas a System.nanoTime () sean menos predecibles.

El siguiente código demuestra el problema.

Ejecutarlo en mi computadora (rMBP 15 "2015, OS X 10.11, jre 1.8.0_40-b26) arroja el siguiente resultado:

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

En una máquina virtual con Windows 8 (VMware Horizon, Windows 8.1, son 1.8.0_60-b27):

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

Sin embargo, ejecutarlo en un servidor empresarial (VMware, RHEL 6.7, jre 1.6.0_45-b06):

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

Lo cual es sorprendentemente el resultado que espero.

Claramente, Thread.sleep (1) afecta el cálculo del siguiente código. No tengo idea de por qué sucede esto. ¿Alguien tiene una pista?

¡Gracias!

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);
    }
}

Básicamente estoy ejecutando una búsqueda dentro de un ciclo while que toma un descanso cada iteración llamando a Thread.sleep (). Quiero excluir el tiempo de reposo del tiempo total necesario para ejecutar la búsqueda, por lo que estoy usando System.nanoTime () para registrar los tiempos de inicio y finalización. Sin embargo, como notó anteriormente, esto no funciona bien.

¿Hay alguna manera de remediar esto?

Gracias por cualquier aportación!

Respuestas a la pregunta(3)

Su respuesta a la pregunta