2011-05-23 7 views
9

El siguiente código:Thread.sleep espera más de lo esperado

long msBefore = System.currentTimeMillis(); 
//Thread.currentThread().setPriority(Thread.MAX_PRIORITY); 
try 
{Thread.sleep(200); 
} catch (InterruptedException e){} 
System.out.println("Time: " + (System.currentTimeMillis() - msBefore)); 

impresiones:

Time: 578 
Time: 594 
Time: 625 
Time: 640 
Time: 641 
Time: 609 
Time: 625 
Time: 625 
Time: 610 
Time: 609 
Time: 625 
Time: 625 
Time: 422 
Time: 625 
Time: 594 
Time: 609 
Time: 625 
Time: 594 
Time: 594 
Time: 625 

¿Dónde está el problema ??

+0

Mientras esté sujeto a la precisión de su sistema, debería estar mucho más cerca que esto. En mis sistemas Windows y Linux, rara vez es más de 2 ms más de lo esperado. ¿Qué sistema operativo tienes? –

+0

Hola, Mohammed. Como han señalado otros, esto estará sujeto a la precisión de sus sistemas (incluso factores ambientales como la temperatura pueden aparecer). Solo por curiosidad, ¿cuál es el problema real que está tratando de resolver con este código? Dependiendo de su respuesta, alguien aquí podría ayudarlo con una mejor manera de hacerlo (por ejemplo, un TimerTaskExecutor sería mucho más preciso para imprimir latidos regulares del corazón). Por favor, asegúrese de plantear la pregunta en un hilo diferente. Aclamaciones. –

+0

Lo he ejecutado varias veces más tarde, y es en gran medida preciso ahora. Gracias a todos por su ayuda. –

Respuesta

7

No hay problema aquí. De javadoc:

sujeta a la exactitud de sistema y programadores.

Por lo general, es un mal diseño depender del intervalo de descanso ya que puede ser diferente en diferentes sistemas e implementaciones de JVM. Use wait() y notify() en su lugar, o mejor: use el paquete java.util.concurrent.

+0

Tengo un requerimiento para enviar n mensajes por segundo, creo que esperar/notificar no encaja, ¿correcto? –

+1

Usa la clase del temporizador para hacer eso. –

+3

wait/notify usa los mismos temporizadores que sleep. Es igual de exacto. –

8

Tengo un requisito para enviar n mensajes por segundo, creo que esperar/notificar no encajan, ¿correcto?

Si usted tiene un requisito de los plazos duro, entonces usted va a necesitar utilizar una aplicación real-time Java. Las implementaciones Mainstream SE y ME Java no son adecuadas para aplicaciones duras en tiempo real.

Existen varios trucos que puede usar para cumplir tales requisitos "la mayor parte del tiempo" ... pero si su aplicación/sistema se sobrecarga, es posible que empiece a perder la tasa de mensajes requerida.

Este problema real no es la precisión de los temporizadores, sino el hecho de que un programador no en tiempo real no garantizará (y no puede) programar el hilo para que se ejecute tan pronto como expire el temporizador.

+0

Gracias por el enlace y la información. –

0

No está teniendo en cuenta el tiempo que tarda en procesarse.

try { 
     long processingStart = System.currentTimeMillis(); 

     long processingFinish = System.currentTimeMillis(); 
     long processTime = 600 - (processingFinish - processingStart); 
     Thread.sleep(processTime); 

    } catch (InterruptedException ex) { 

    } 
0

Si realmente necesita una velocidad de mensajes fija, implemente algo así como un bloqueo de giro. Consumirá un solo núcleo de CPU, pero te acercará.

long nextTime = System.currentTimeMillis() + interval; 
while (keepRunning) { 
    while (nextTime - System.currentTimeMillis() > 0) 
     ; 
    sendMessage(); 
    nextTime += interval; 
} 
Cuestiones relacionadas